Python kivy restart game - python

I'm making a game in kivy, it's a soccer juggling game. I want the game to be over whenever the soccer ball falls off the screen, also I want a restart button when the game is over so I can play again. I tried a lot of things but it doesn't seem to work. Any help is appreciated. Below is my code! Thank You!
main.py
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.image import Image
from kivy.core.audio import SoundLoader
from kivy.clock import Clock
from kivy.properties import NumericProperty
from kivy.vector import Vector
class HomeScreen(Screen):
pass
def play_sound(self):
sound = SoundLoader.load('button press sound.wav.')
if sound:
sound.play()
sound = SoundLoader.load('Crowd sound effect.wav')
sound.loop = True
sound.play()
class GameScreen(Screen):
pass
def play_sound(self):
sound = SoundLoader.load('button press sound.wav.')
if sound:
sound.play()
class Ball(Image):
velocity = NumericProperty(0)
def on_touch_down(self, touch):
if Vector(self.center).distance(touch.pos) <= 33:
label = App.get_running_app().root.get_screen('game_screen').ids.score
label.text = str(int(label.text) + 1)
sound = SoundLoader.load('Soccer ball sound.wav')
sound.play()
self.source = "icons/ball.png"
self.velocity = 275
return super().on_touch_down(touch)
def on_touch_up(self, touch):
if Vector(self.center).distance(touch.pos) <= 33:
self.source = "icons/ball.png"
return super().on_touch_up(touch)
class MainApp(App):
GRAVITY = 300
def move_ball(self, time_passed):
ball = self.root.ids.game_screen.ids.ball
ball.y = ball.y + ball.velocity * time_passed
ball.velocity = ball.velocity - self.GRAVITY * time_passed
self.check_collision()
def check_collision(self):
ball = self.root.ids.game_screen.ids.ball
if ball.top < 96:
self.game_over()
def game_over(self):
print("game over")
def start_game(self):
Clock.schedule_interval(self.move_ball, 1/60.)
self.root.ids.game_screen.ids.score.text = "0"
def change_screen(self, screen_name):
self.root.current = screen_name
MainApp().run()
homescreen.kv
#:import utils kivy.utils
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
<HomeScreen>:
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#39B3F2")
Rectangle:
size: self.size
pos: self.pos
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .9
Image:
source: "icons/keepyup.png"
FloatLayout:
Button:
font_size: dp(20)
font_name: 'SackersGothicStd-Medium.otf'
text: "PLAY"
color: "gold"
pos_hint: { "center_x": .5, "center_y": .3}
size: 80, 55
size_hint: None, None
background_normal: ''
background_color: (57/255.0, 179/255.0, 242/255.0, .10)
on_press:
on_release:
root.play_sound()
root.manager.transition = FadeTransition()
app.change_screen("game_screen")
gamescreen.kv
#:import utils kivy.utils
<GameScreen>:
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#39B3F2")
Rectangle:
size: self.size
pos: self.pos
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .1
Image:
source: "icons/sun.png"
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .2
Image:
source: "icons/clouds.png"
GridLayout:
rows: 1
pos_hint: {"bottom": 1, "left": 1}
size_hint: 1, .5
Image:
source: "icons/Field4.png"
allow_stretch: True
keep_ratio: False
pos: self.pos
Label:
id: score
size_hint: None, None
font_size: dp(25)
font_name: 'SackersGothicStd-Medium.otf'
text: "0"
color: "gold"
pos_hint: { "center_x": 0.1, "center_y": 0.9}
Button:
size_hint: None, None
font_size: dp(20)
font_name: 'SackersGothicStd-Medium.otf'
text: "Start Game"
color: "gold"
pos_hint: { "center_x": 0.5, "center_y": 0.3}
size: 150, 55
size_hint: None, None
background_normal: ''
background_color: (57/255.0, 179/255.0, 242/255.0, .10)
on_release:
self.disabled = True
self.opacity = 0
root.play_sound()
app.start_game()
Ball:
source: "icons/ball.png"
size_hint: None, None
size: 500, 500
pos_hint: {"center_x": 0.5}
id: ball
main.kv
#:include kv/homescreen.kv
#:include kv/gamescreen.kv
ScreenManager:
id: screen_manager
HomeScreen:
name: "home_screen"
id: home_screen
GameScreen:
name: "game_screen"
id: game_screen

Firstly, define a name for clock so you can stop it when game over:
self.control = Clock.schedule_interval(self.move_ball, 1/60.)
In game_over func, let's stop this clock:
self.control.cancel()
Now we need to create BoxLayout for our popup: ( game_over function )
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.button import Button
bx = BoxLayout(orientation='vertical')
restart_but = Button(text='Restart')
restart_but.bind(on_release=self.restart_game)
bx.add_widget(Label(text='Score :'+self.root.ids.game_screen.ids.score.text))
bx.add_widget(restart_but)
self.popup = Popup(title='Game Over',content=bx,size_hint=(None, None), size=(400, 400))
self.popup.open()
Now as we define release command to restart_but, need to create new function:
def restart_game(self,*args):
self.popup.dismiss() #Close popup
#default settings here..
self.control = Clock.schedule_interval(self.move_ball, 1/60.) #Start Game
In restart_game function, you need to reset all settings like ball's position and score.
Also I suggest you to use KivyMD for sightly popups and buttons.

Related

split gridlayout to can not draw in paint app kivy python

I designed this program
python code:
from random import random
from kivymd.app import MDApp as App
from kivymd.uix.widget import MDWidget as Widget
from kivy.graphics import Ellipse, Color, Line
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.button import MDIconButton
from kivy.lang import Builder
from kivy.properties import ObjectProperty
class Main(Screen):
draw = ObjectProperty(None)
class About(Screen):
pass
class Manager(ScreenManager):
mgr = ObjectProperty(None)
def cleaner(self):
self.mgr.draw.clean()
def color(self,color):
MyPaintWidget.color = color
class MyPaintWidget(Widget):
color = (0,0,0,1)
def clean(self):
self.canvas.clear()
def on_touch_down(self, touch):
# self.rect.pos = touch.pos
color = self.color
with self.canvas:
Color(*color)
d = 10
touch.ud['line'] = Line(points=(touch.x, touch.y),width = 5)
def on_touch_up(self,touch):
with self.canvas:
d = 10
Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
def on_touch_move(self, touch):
# self.rect.pos = touch.pos
touch.ud['line'].points += [touch.x, touch.y]
#main_style = Builder.load_file("ms_paint.kv")
class MyPaintApp(App):
def build(self):
self.root = Builder.load_file("ms_paint.kv")
if __name__ == '__main__':
MyPaintApp().run()
kv file:
#:import get_color_from_hex kivy.utils.get_color_from_hex
Manager:
mgr: sc_mgr
Main:
id: sc_mgr
About:
<MyPaintWidget>:
on_touch_down: self.on_touch_down
on_touch_move: self.on_touch_move
<Main>:
name: "main"
draw: main_draw
BoxLayout:
orientation: "vertical"
MyPaintWidget:
id: main_draw
size_hint: 1, 0.9
GridLayout:
size_hint: 1, 0.1
cols: 7
padding: 10
#Button:
#text: "About"
#on_press:
#root.manager.current= "about"
#root.manager.transition.direction= "left"
MDIconButton:
icon: "eraser-variant"
on_press: root.manager.cleaner()
MDIconButton:
icon: "circle"
theme_icon_color: "Custom"
icon_color: (0,0,0,1)
on_press: root.manager.color((0,0,0,1))
MDIconButton:
icon: "circle"
theme_icon_color: "Custom"
icon_color: get_color_from_hex("#ff0000")
on_press: root.manager.color((255,0,0,1))
MDIconButton:
icon: "circle"
theme_icon_color: "Custom"
icon_color: get_color_from_hex("#00ff00")
on_press: root.manager.color((0,255,0,1))
MDIconButton:
icon: "circle"
theme_icon_color: "Custom"
icon_color: get_color_from_hex("#0000ff")
on_press: root.manager.color((0,0,255,1))
<About>:
name: "about"
BoxLayout:
orientation: "vertical"
padding: 10
Label:
size_hint: 1, 0.9
text: "This is a free and open source paint app, made by a teacher of HamRuyesh community."
Button:
size_hint: 1, 0.9
text:"Back to Main"
on_press:
root.manager.current= "main"
root.manager.transition.direction= "right"
My problem is that I do not want to draw a line in the bottom bar, which is a grid layout, and I just want to be able to draw from that part. please guide me.
..........................................................................................................................................
You can use StencilView to limit the drawing area.
Thus You might change the MyPaintWidget(Widget) as
class MyPaintWidget(BoxLayout, StencilView):

how to solve kivy widget error "only one root object is allowed by .kv"

First I want to say I just started learning maybe 2 months ago so I don't really know how to phrase my question. so if the Question title is misleading I'm sorry.
basically I'm working on a project and I want to learn how to add projects I've already done inside an like the pong game (pong.py and pong.kv) I made and I want to see if I can use the simple app (main.py, main.kv, playscreen.kv, settingscreen.kv, aboutscreen.kv)I made to run the pong game. Basically I'm trying to make the main app be able to navigate to the playscreen and then be able to play pong
I cant even remember all the things I've tried but when I think I get close I end up seeing a black screen or I just see the pong screen which is the problem I'm having now.
Main.py
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager
from kivymd.app import MDApp
from kivymd.uix.screen import Screen
class HomeScreen(Screen):
pass
class SettingScreen(Screen):
pass
class AboutScreen(Screen):
pass
class PlayScreen(Screen):
pass
class PlayPong(Screen):
pass
#GUI = Builder.load_file("main.kv")
class MainApp(MDApp):
def build(self):
self.root = Builder.load_file("main.kv")
self.theme_cls.primary_palette = "Teal"
def change_screen(self,screen_name):
screen_manager = self.root.ids['screen_manager']
screen_manager.current = screen_name
ScreenManager.transition
#screen_manager.play_pong = Builder.load_file("kv/pong.py")
if __name__ == "__main__":
MainApp().run()
Main.kv
#:include kv/homescreen.kv
#:include kv/settingscreen.kv
#:include kv/aboutscreen.kv
#:include kv/playscreen.kv
#:include kv/playpong.kv
GridLayout:
cols: 1
ScreenManager:
id: screen_manager
HomeScreen:
name: "home_screen"
id: home_screen
SettingScreen:
name: "setting_screen"
id: setting_screen
AboutScreen:
name:"about_screen"
id: about_screen
PlayScreen:
name:"play_screen"
id: play_screen
PlayPong:
name: "play_pong"
id: "play_pong"
playpong.kv
#:import PongApp kv.pong.PongApp
#:import App kivy.app.App
<PlayPong>:
#PongApp().run()
homescreen.kv
#:include kivymd/MDApp.py
#:include kivymd/uix/button.py/MDFloatingActionButton/MDFlatButton
#:include kivymd/uix/screen.py/Screen
#:import MDFillRoundFlatButton kivymd.uix.button.MDFillRoundFlatButton
#:import Builder kivy.lang.Builder
<HomeScreen>:
FloatLayout:
BoxLayout:
orientation: 'horizontal'
MDToolbar:
pos_hint: {"center_x": .95, "center_y": .97}
title: 'Main Menu'
elevation:10
left_action_items: [["home", lambda x: x]]
right_action_items: [["book", lambda x: x]]
MDFillRoundFlatButton:
pos_hint: {"center_x": .5, "center_y": .3}
size_hint: .8,.1
md_bg_color: [.200,.150,.150,.3]
text: "Settings"
on_release:
app.change_screen("setting_screen")
root.manager.transition.direction = 'right'
MDFillRoundFlatButton:
pos_hint: {"center_x": .5, "center_y": .5}
size_hint: .8,.1
md_bg_color: [.200,.150,.150,.3]
text: "about"
on_release:
app.change_screen("about_screen")
root.manager.transition.direction = 'right'
MDFillRoundFlatButton:
pos_hint: {"center_x": .5, "center_y": .7}
size_hint: .8,.1
md_bg_color: [.200,.150,.150,.3]
text: "play"
on_release:
app.change_screen("play_screen")
root.manager.transition.direction = 'right'
playscreen.kv
<PlayScreen>:
FloatLayout:
BoxLayout:
orientation: 'horizontal'
MDToolbar:
pos_hint: {"center_x": .95, "center_y": .95}
title: 'Game Menu'
elevation:10
left_action_items: [["devices", lambda x: x]]
right_action_items: [["gesture", lambda x: x]]
MDFillRoundFlatButton:
pos_hint: {"center_x": .5, "center_y": .5}
size_hint: .6,.1
text: "Main Menu"
md_bg_color: [.200,.150,.150,.3]
on_release:
app.change_screen("home_screen")
root.manager.transition.direction = 'right'
MDFillRoundFlatButton:
pos_hint: {"center_x": .5, "center_y": .3}
size_hint: .6,.1
text: "Play Pong"
md_bg_color: [.200,.150,.150,.3]
on_release:
app.change_screen("play_pong")
root.manager.transition.direction = 'right'
settingscreen.kv
#:include kivymd/MDApp.py
#:include kivymd/uix/button.py/MDFloatingActionButton/MDFlatButton
#:include kivymd/uix/screen.py/Screen
#:import MDFillRoundFlatButton kivymd.uix.button.MDFillRoundFlatButton
#:import Builder kivy.lang.Builder
<SettingScreen>:
FloatLayout:
BoxLayout:
orientation: 'horizontal'
MDToolbar:
pos_hint: {"center_x": .95, "center_y": .95}
title: 'Settings'
left_action_items: [["settings", lambda x: x]]
right_action_items: [["dns", lambda x: x]]
elevation:10
MDFillRoundFlatButton:
pos_hint: {"center_x": .5, "center_y": .5}
size_hint: .6,.1
text: "Main Menu"
md_bg_color: [.200,.150,.150,.3]
on_release:
app.change_screen("home_screen")
root.manager.transition.direction = 'left'
aboutscreen.kv
<AboutScreen>:
FloatLayout:
BoxLayout:
orientation: 'horizontal'
MDToolbar:
pos_hint: {"center_x": .95, "center_y": .95}
title: 'About The Game and Creator'
elevation:10
left_action_items: [["emoticon", lambda x: x]]
right_action_items: [["library", lambda x: x]]
Label:
pos_hint: {"top":.9 , "left":.5}
size_hint: 1,.2
text:
"About the app and the creator"
MDFillRoundFlatButton:
pos_hint: {"center_x": .5, "center_y": .5}
size_hint: .6,.1
text: "Main Menu"
on_release:
app.change_screen("home_screen")
root.manager.transition.direction = 'right'
pong.py
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty
from kivy.vector import Vector
from kivy.clock import Clock
from random import randint
class PongPaddle(Widget):
score = NumericProperty(0)
def bounce_ball(self,ball):
if self.collide_widget(ball):
ball.velocity_x *= -1.1
class PongBall(Widget):
velocity_x = NumericProperty(0)
velocity_y = NumericProperty(0)
velocity = ReferenceListProperty(velocity_x,velocity_y)
# latest postion = Current velocity + Current Position
def move(self):
self.pos = Vector(*self.velocity) + self.pos
# moving the ball by calling move function
class PongGame(Widget):
ball = ObjectProperty(None)
player1 = ObjectProperty(None)
player2 = ObjectProperty(None)
def serve_ball(self):
self.ball.velocity = Vector(4, 0).rotate(randint(0,360))
def update(self, dt):
self.ball.move()
# bounce off top and bottom
if (self.ball.y < 0) or (self.ball.y > self.height -30):
self.ball.velocity_y *= -1
# bounce off left and increase score
if self.ball.x < -30:
self.ball.velocity_x *= -1
self.player1.score += 1
# bounce of right
if self.ball.x > self.width:
self.ball.velocity_x *= -1
self.player2.score += 1
self.player1.bounce_ball(self.ball)
self.player2.bounce_ball(self.ball)
def on_touch_move(self, touch):
if touch.x < self.width / 1/4:
self.player1.center_y = touch.y
if touch.x > self.width * 3/4:
self.player2.center_y = touch.y
class PongApp(App):
def build(self):
game = PongGame()
game.serve_ball()
Clock.schedule_interval(game.update,0/60.0)
return game
if __name__ == "__main__":
PongApp().run()
pong.kv
<PongPaddle>:
size: 20,200
canvas:
Color:
rgba: 1,0,0,1
Rectangle:
pos: self.pos
size: self.size
<PongBall>:
size: 30,30
canvas:
Ellipse:
pos: self.pos
size: self.size
<PongGame>:
ball : pong_ball
player1 : player_left
player2 : player_right
canvas:
Color:
rgba: 0,0,1,1
Rectangle:
pos: self.center_x - 5, 0
size: 10, self.height
Label:
font_size: 70
center_x: root.width / 4
top: root.top - 30
text: str(root.player2.score)
Label:
font_size: 70
center_x: root.width * 3/4
top: root.top - 30
text: str(root.player1.score)
PongBall:
id : pong_ball
center: self.parent.center
PongPaddle:
id:player_left
x : root.x
center_y : root.center_y
PongPaddle:
id:player_right
x : root.width - self.width
center_y : root.center_y
So after I updated my app I'm still getting a widget error
1:from kivy.app import App
>> 2:from kivy.uix.widget import Widget
3:from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty
4:from kivy.vector import Vector
...
Only one root object is allowed by .kv
Ive tried playing with the classes to try and only make one widget but then that messes up the code and I get other errors
I've also tried writing all the Pong.py code into my Main.py file but that didn't seem to work either.
Anyways thanks for the help!
The reason that you are seeing the pong game is because of the line:
PongApp().run()
Which starts the pong game as soon as you import that file.
Replace that line with:
if __name__ == "__main__":
PongApp().run()
That protects the running of PongApp unless pong.py is run directly by python, and not just imported.

Problems with changing text of button when using MDDropdownMenu

I have problems with giving the text of my button when clicking on the label in list from MDDropdownMenu. In my testing main.py and main.kv it has been working, but when it was implemented in main code - it has an error AttributeError: 'super' object has no attribute '__getattr__'
There is my main.py:
# encoding=utf8
import sys
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.popup import Popup
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.image import Image
from kivy.core.text import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.screenmanager import SlideTransition
from kivy.properties import ObjectProperty, NumericProperty, StringProperty, BooleanProperty, ListProperty
from kivy.utils import get_hex_from_color
from kivy.metrics import dp, sp, pt
from kivy.clock import Clock
from kivy.uix.textinput import TextInput
from kivymd.theming import ThemeManager
from kivymd.dialog import MDDialog
from kivymd.label import MDLabel
from kivymd.button import MDRoundFlatButton
from kivymd.button import MDRaisedButton
from kivymd.list import ILeftBodyTouch
from kivymd.popupscreen import MDPopupScreen
from newpickers import MDDatePicker
from kivymd.menus import MDDropdownMenu
year1 = 0
monthlist = ['Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь',]
monthnum = 0
selected_date = ''
class Manager(ScreenManager):
def __init__(self, **kwargs):
super(Manager, self).__init__(**kwargs)
class MainMenu(Screen):
pass
class InfoMenu(Screen):
pass
class ListButton(MDRaisedButton):
pass
class DateSetupMenu(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.menu_items = [
{
"viewclass": "MDMenuItem",
"text": "%d" % i,
"callback": self.callbackforlist,
}
for i in range(1900, 2100)
]
def callbackforlist(self, *args):
pass
class Year_layout_popup1(GridLayout):
pass
class Year_layout_scrollview1(ScrollView):
pass
class YearButton1(MDRaisedButton):
pass
class YearSelectionButton(MDRoundFlatButton):
def on_release(self):
global year1
year1 = int(self.text)
class DatePickPopup(Popup):
pass
class Month_layout_popup(GridLayout):
pass
class Month_layout_scrollview(ScrollView):
pass
class MonthButton(MDRaisedButton):
pass
class DatePickerWidget(MDDatePicker):
pass
class MonthSelectionButton(MDRoundFlatButton):
def on_release(self):
global monthlist
global monthnum
monthnum = int(monthlist.index(str(self.text)))
monthnum += 1
class MonthPickPopup(Popup):
pass
class yearselectbtn(Button):
pass
class monthselectbtn(Button):
pass
class rt_android(App):
theme_cls = ThemeManager()
theme_cls.device_orientation == 'portrait'
title = 'Rectif Tattva Android Edition'
yearselectlabeltext = StringProperty('Выберите год рождения')
monthselectlabeltext = StringProperty('Выберите месяц рождения')
dateselectlabeltext = StringProperty('Выберите день рождения')
mlist = ['Месяц','Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь']
VARIABLE = ""
def build(self):
self.theme_cls.theme_style = 'Light'
Window.size = (480, 854)
return Manager()
def CloseExitPopup(self, *args):
from kivymd.toast.kivytoast import toast
if args[0] == 'Да':
App.get_running_app().stop()
else:
pass
def ExitDialog(self):
self.dialog = MDDialog(
title='Выход из приложения', size_hint=(.8, .25), text_button_ok='Нет',
text="Вы точно хотите выйти?",
text_button_cancel='Да',
events_callback=self.CloseExitPopup)
self.dialog.open()
def OpenDatePicker(self, *args):
DatePickerWidget(self.set_date, year1, monthnum, 1).open()
def set_date(self, date_obj):
global selected_date
global year1
global monthnum
global daynum
self.setupdate = date_obj
selected_date = str(self.setupdate)
year1 = int(selected_date[0:4])
monthnum = int(selected_date[5:7])
daynum = int(selected_date[8:10])
month_id = monthnum-1
def year_select_clicked1(self):
self.ylp = Year_layout_popup1()
self.ylp.bind(minimum_height=self.ylp.setter('height'))
# for i in range(1950, 2019):
# self.ysb = YearSelectionButton()
# self.ysb.text = str(i)
# self.ylp.add_widget(self.ysb)
for i in range(1950, 2019):
self.ysb = yearselectbtn()
self.ysb.text = str(i)
self.ylp.add_widget(self.ysb)
root = Year_layout_scrollview1()
root.add_widget(self.ylp)
self.popup = DatePickPopup()
self.popup.content = root
self.popup.open()
def month_select_clicked(self):
global monthlist
self.mlp = Month_layout_popup()
self.mlp.bind(minimum_height=self.mlp.setter('height'))
# for i in range(0, 12):
# self.msb = MonthSelectionButton()
# self.msb.text = str(monthlist[i])
# self.msb.id = str(i)
# self.mlp.add_widget(self.msb)
for i in range(0, 12):
self.msb = monthselectbtn()
self.msb.text = str(monthlist[i])
self.msb.id = str(i)
self.mlp.add_widget(self.msb)
root = Month_layout_scrollview()
root.add_widget(self.mlp)
self.popup_m = DatePickPopup()
self.popup_m.content = root
self.popup_m.open()
def closeitpls(self):
self.popup.dismiss()
def closeitpls_m(self):
self.popup_m.dismiss()
def change_variable(self, value):
print("\nvalue=", value)
self.VARIABLE = value
print("\tself.VARIABLE=", self.VARIABLE)
class CreditsImage(Image):
pass
with open("main_interface.kv", encoding='utf8') as f:
main_interface = Builder.load_string(f.read())
if __name__ == '__main__':
rt_android().run()
And there is my main_interface.kv:
# encoding=utf8
#:import SlideTransition kivy.uix.screenmanager.SlideTransition
#:import Factory kivy.factory.Factory
#:import MDLabel kivymd.label.MDLabel
#:import MDRaisedButton kivymd.button.MDRaisedButton
#:import MDRectangleFlatButton kivymd.button.MDRectangleFlatButton
#:import MDToolbar kivymd.toolbar.MDToolbar
#:import MDRoundFlatButton kivymd.button.MDRoundFlatButton
#:import MDDropdownMenu kivymd.menus.MDDropdownMenu
#:import MDMenuItem kivymd.menus.MDMenuItem
#:import hex kivy.utils.get_color_from_hex
#:set white hex('#00a86b')
<MenuButton#MDRaisedButton>:
font_size: dp(8)
elevation_normal: 3
pos_hint: {'center_x': .5, 'center_y': .5}
size_hint_x: 0.5
height: dp(50)
<InfoMenuButton#MDRaisedButton>:
font_size: dp(8)
elevation_normal: 3
pos_hint: {'center_x': .5, 'center_y': .5}
size_hint: None, None
height: dp(50)
<DateSetupMenuButton#MDRaisedButton>:
font_size: dp(8)
elevation_normal: 3
pos_hint: {'center_x': .5, 'center_y': .5}
size_hint: None, None
height: dp(50)
<Year_layout_popup1>:
cols: 1
spacing: 15
padding: [10,10,10,10]
size_hint_y: None
<Year_layout_scrollview1>:
size_hint: (1, None)
size: Window.width*0.8, Window.height*0.7
<YearButton1>:
font_size: dp(8)
elevation_normal: 3
pos_hint: {'center_x': .5, 'center_y': .5}
size_hint: None, None
height: dp(50)
<DatePickPopup>:
title: 'Выбор года рождения'
size_hint: 0.8, 0.8
auto_dismiss: False
separator_color: white
title_color: white
background: 'assets/whiteback.png'
<YearSelectionButton>:
font_size: dp(8)
pos_hint: {'center_x': .5, 'center_y': .5}
size_hint: 1, None
height: dp(50)
on_press:
app.yearselectlabeltext = self.text
on_release:
app.closeitpls()
<Month_layout_popup>:
cols: 1
spacing: 15
padding: [10,10,10,10]
size_hint_y: None
<Month_layout_scrollview>:
size_hint: (1, None)
size: Window.width*0.8, Window.height*0.7
<MonthButton>:
font_size: dp(8)
elevation_normal: 3
pos_hint: {'center_x': .5, 'center_y': .5}
size_hint: None, None
height: dp(50)
<MonthPickPopup>:
title: 'Выбор месяца рождения'
size_hint: 0.8, 0.8
auto_dismiss: False
separator_color: white
title_color: white
background: 'assets/whiteback.png'
<MonthSelectionButton>:
id: ''
font_size: dp(8)
pos_hint: {'center_x': .5, 'center_y': .5}
size_hint: 1, None
height: dp(50)
on_press:
app.monthselectlabeltext = self.text
on_release:
app.closeitpls_m()
<yearselectbtn>:
font_size: dp(16)
pos_hint: {'center_x': .5, 'center_y': .5}
size_hint: 1, None
height: dp(50)
background_color: (255, 255, 255, 1)
color: (0,0,0,1)
on_press:
app.yearselectlabeltext = self.text
on_release:
app.closeitpls()
<monthselectbtn>:
font_size: dp(16)
pos_hint: {'center_x': .5, 'center_y': .5}
size_hint: 1, None
height: dp(50)
background_color: (255, 255, 255, 1)
color: (0,0,0,1)
on_press:
app.monthselectlabeltext = self.text
on_release:
app.closeitpls_m()
<MDMenuItem>:
on_release:
app.root.ids.buttonoflist.text = self.text
<ListButton>:
id: buttonoflist
font_size: dp(8)
pos_hint: {'center_x': .5, 'center_y': .5}
size_hint: None, None
height: dp(50)
<Manager>:
MainMenu:
name: 'main_menu'
InfoMenu:
name: 'info_menu'
DateSetupMenu:
name: 'date_setup_menu'
<MainMenu>:
AnchorLayout:
anchor_y: 'top'
MDToolbar:
title: app.title
elevation: 10
md_bg_color: white
AnchorLayout:
anchor_y: 'bottom'
BoxLayout:
orientation: 'vertical'
size_hint: 0.95, 0.25
spacing: dp(10)
padding: [0, 0, 0, dp(10)]
MenuButton:
text: 'Приступить'
on_press:
app.root.transition = SlideTransition(direction='left', duration = .17)
on_release:
root.manager.current = 'date_setup_menu'
MenuButton:
text: 'Инфо'
on_press:
app.root.transition = SlideTransition(direction='left', duration = .17)
on_release:
root.manager.current = 'info_menu'
MenuButton:
text: 'Выход'
on_release:
app.ExitDialog()
<InfoMenu>:
AnchorLayout:
anchor_y: 'top'
MDToolbar:
title: 'Инфо'
elevation: 10
md_bg_color: white
BoxLayout:
size_hint_y: 0.4
orientation: 'vertical'
spacing: 5
padding: [0, dp(90), 0, 0]
pos_hint: {'center_x': .5, 'center_y': 1}
CreditsImage:
source: 'assets/info_credits_table.png'
size_hint_y: 0.8
MDLabel:
text: 'версия программы: 1.0.0'
font_name: 'assets/Ponter.ttf'
color: (255,255,255,1)
size_hint_y: 0.2
font_size: dp(20)
halign: 'center'
valign: 'top'
text_size: self.size
AnchorLayout:
anchor_y: 'bottom'
BoxLayout:
orientation: 'vertical'
size_hint: 0.95, 0.25
padding: [0, 0, 0, dp(15)]
InfoMenuButton:
text: 'Назад'
on_press:
app.root.transition = SlideTransition(direction='right', duration = .17)
on_release:
root.manager.current = 'main_menu'
<DateSetupMenu>:
AnchorLayout:
anchor_y: 'top'
MDToolbar:
title: 'Выбор параметров'
elevation: 10
md_bg_color: white
AnchorLayout:
anchor_y: 'center'
BoxLayout:
orientation: 'vertical'
size_hint: 0.95, 0.25
padding: [0, dp(15), 0, 0]
spacing: dp(5)
ListButton:
id: buttonoflist
text: 'Выбор'
on_release:
MDDropdownMenu(items=root.menu_items, width_mult=4).open(self)
YearButton1:
text: app.yearselectlabeltext
on_release:
app.year_select_clicked1()
MonthButton:
text: app.monthselectlabeltext
on_release:
app.month_select_clicked()
DateSetupMenuButton:
text: app.dateselectlabeltext
on_release:
app.OpenDatePicker()
AnchorLayout:
anchor_y: 'bottom'
BoxLayout:
orientation: 'vertical'
size_hint: 0.95, 0.25
padding: [0, 0, 0, dp(15)]
DateSetupMenuButton:
text: 'Назад'
on_press:
app.root.transition = SlideTransition(direction='right', duration = .17)
on_release:
root.manager.current = 'main_menu'
I need to change the text of «ListButton» object after clicking MDMenuItem proreply. I dont know, why it is working in standalone code, but in my main code it has that horrible problem...
Errors - KeyError & AttributeError
Traceback (most recent call last):
File "kivy/properties.pyx", line 860, in kivy.properties.ObservableDict.__getattr__
KeyError: 'buttonoflist'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
...
File ".../main.kv", line 132, in <module>
app.root.ids.buttonoflist.text = self.text
File "kivy/properties.pyx", line 863, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'
Root Cause
The first error encountered was KeyError because the id, 'buttonoflist' does not exist in Kivy self.ids dictionary type property.
The second error encountered was AttributeError because the id, 'buttonoflist' does not exist in the root (which is a ScreenManager).
Solution
Since id: buttonoflist is declared in the Screen,
DateSetupMenu:, you have to add an id to DateSetupMenu object so
that you can access / reference it.
Replace app.root.ids.buttonoflist.text with app.root.ids.date_setup_menu.ids.buttonoflist.text
Snippets - kv file
<MDMenuItem>:
on_release:
app.root.ids.date_setup_menu.ids.buttonoflist.text = self.text
...
<Manager>:
...
DateSetupMenu:
id: date_setup_menu
name: 'date_setup_menu'
...
Output

Increment, Decrement, and clear with buttons kivy

I'm a beginner so please excuse the simplistic question. I'm trying to create a control screen that displays a count. Essentially I want it to get a low signal on one of the GPIO's and advance one integer. I also want the ability to edit the count with "+", "-", and "clear" buttons. This is one of the first bits of code I've ever written so I may be way off base here! Here is the code for the .py:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
import RPi.GPIO as GPIO
startPin = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(startPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
class InputButton(Button):
def update(self, dt):
if GPIO.input(startPin) == True:
self.ids.textbox.text +=1
class MainWidget(FloatLayout):
def adv_callback(self, text):
self.ids.textbox.text += 1
def fall_callback(self, text):
self.ids.textbox.text -= 1
def clear_callback(self, text):
self.ids.textbox.text = 0
class MainApp(App):
'''docstring for MainApp'''
def build(self):
return MainWidget()
if __name__=="__main__":
MainApp().run()
and the .kv
# File name main.py
<MainWidget>:
canvas.before:
Color:
rgba: .95, .95, 1, .7
Rectangle:
pos: self.pos
size: self.size
Button:
id: clear
text: 'Clear'
font_size: '50sp'
pos: (650, 0)
size_hint: .2, .3
on_press: root.clear_callback(self.text)
Button:
id: add
text: '+'
font_size: '50sp'
pos: (0, 142)
size_hint: .2, .3
on_press: root.adv_callback(self.text)
Button:
id: less
text: '-'
font_size: '50sp'
pos: (0, 0)
size_hint: .2, .3
on_press: root.fall_callback(self.text)
AsyncImage:
source: '/home/sysop/Pictures/Source_Files_Pocono_logo_on_White_Bg.gif'
size_hint: .5, .3
pos: (200, 285)
TextInput:
id: textbox
multiline: False
readonly: True
size_hint: .5, .3
font_size: '80sp'
pos: (325, 0)
ActionBar:
pos: (0, 432)
ActionView:
ActionPrevious:
title: ""
with_previous: False
ActionOverflow:
ActionButton:
text: "Shutdown"
on_press: app.open_settings()

Can't include the pong game on one of two screens - kivy

That's my error:
AttributeError: 'NoneType' object has no attribute 'move'
I have been searching, looking kivy videos and trying a lot of things but I can't get the ball of the Pong Game tutorial to work on my GameScreen when I press Play in StartScreen.
Sometimes i don't get an error but only when the game isn't on the screen. The app then works normally and the ball (snake snaky) does show on the right SnakeWidget widget, but i can't change its position even with typing the exact position.
.py:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.core.window import Window
from kivy.core.image import Image
from kivy.graphics import Color, Rectangle
from kivy.uix.popup import Popup
from kivy.uix.bubble import Bubble
from kivy.properties import NumericProperty, ReferenceListProperty
from kivy.properties import ObjectProperty
from kivy.vector import Vector
from kivy.clock import Clock
from kivy.lang import Builder
from random import randint
class InfoWidget(Widget):
score = NumericProperty(0)
class Snake(Widget):
velocity_x = NumericProperty(0)
velocity_y = NumericProperty(0)
velocity = ReferenceListProperty(velocity_x, velocity_y)
def move(self):
self.pos = Vector(*self.velocity) + self.pos
class SnakeWidget(Widget):
snaky = ObjectProperty(None)
def __init__(self, *args, **kwargs):
super(SnakeWidget, self).__init__(*args, **kwargs)
Clock.schedule_interval(self.update, 1.0 / 60.0)
def begin(self, vel=(4, 0)):
self.snaky.center = self.center
self.snaky.velocity = vel
def update(self, dt):
self.snaky.move()
class InfoWidget(Widget):
score = NumericProperty(0)
class StartScreen(Screen):
snake_widget = SnakeWidget()
Clock.schedule_interval(snake_widget.update, 1.0 / 60.0)
class GameScreen(Screen):
pass
class RootScreen(ScreenManager):
pass
class Main2App(App):
def build(self):
self.load_kv("main2.kv")
return RootScreen()
if __name__ == "__main__":
Main2App().run()
.kv file:
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
<StartScreen>:
name: "start"
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: "lights.png"
FloatLayout:
Button:
id: "play"
background_color: 0.012, 0.227, 0.11, 0.1
text: "Play!"
size_hint: 0.4, 0.3
pos_hint: {'center_x':.5, 'center_y':.5}
font_size: 70
on_release: root.current = 'game'; snake_widget.begin()
Button:
id: "how"
background_color: 0.012, 0.227, 0.11, 0.1
text: "How to play"
size_hint: 0.4, 0.1
pos_hint: {"center_x":.5, "center_y":.3}
font_size: 40
<GameScreen>:
name: "game"
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: "lights.png"
FloatLayout:
SnakeWidget:
InfoWidget:
Button:
id: menu
size_hint: 0.2, 0.1
pos_hint: {"x": 0.8,"y":0.9}
background_color: 0.012, 0.227, 0.11,0.3
text: "Menu"
font_size: 17
on_release: root.manager.current = "start"
Button:
id: levo
size_hint: 0.1, 0.1
pos_hint: {"x": 0.8,"y":0}
background_color: 0.012, 0.227, 0.11,0.3
text: "<"
font_size: 20
Button:
id: desno
size_hint: 0.1, 0.1
pos_hint: {"x": 0.9,"y":0}
background_color: 0.012, 0.227, 0.11,0.3
text: ">"
font_size: 20
<Snake>:
size: 50, 50
canvas:
Color:
rgba: 1,1,1,1
Ellipse:
pos: self.pos
size: 40, 40
source: "snaky.png"
<SnakeWidget>:
id: snake_widget
snaky: snake
size_hint: 0.797, 1
pos_hint: {"x": 0,"center_y":0.5}
canvas:
Color:
rgba: 1,1,1,0.07
Rectangle:
size: self.size
pos: self.pos
Snake:
id: snake
center: self.parent.center
<InfoWidget>:
size_hint: 0.2, 0.799
pos_hint: {"x": 0.8014,"y":0.101}
canvas.before:
Color:
rgba: 0.010, 0.227, 0.17, 0.005
Rectangle:
size: self.size
pos: self.pos
Label:
canvas.before:
Color:
rgba: 0.010, 0.227, 0.17, 0.005
Rectangle:
size: root.parent.width*0.192, root.parent.height*0.06
pos: root.parent.width*0.805, root.parent.height*0.837
id: "result"
text: "Result:"
font_size: 17
pos: root.parent.width*0.79, root.parent.height*0.78
Label:
canvas.before:
Color:
rgba: 0.012, 0.227, 0.15, 0.005
Rectangle:
size: root.parent.width*0.192, root.parent.height*0.06
pos: root.parent.width*0.805, root.parent.height*0.77
id: "record"
text: "Record:"
font_size: 17
pos: root.parent.width*0.79, root.parent.height*0.72
<RootScreen>:
id: screen_manager
transition: FadeTransition()
StartScreen:
name: "start"
GameScreen:
name: "game"
Sorry for all the code, but I really don't know what to try anymore.
In line 35,
class SnakeWidget(Widget):
snaky = ObjectProperty(Snake())
Snaky should be an instance of Snake.
Try something Like this:
.py is here...
class PongPaddle(Widget):
score = NumericProperty(0)
def bounce_ball(self, ball):
if self.collide_widget(ball):
vx, vy = ball.velocity
offset = (ball.center_y - self.center_y) / (self.height / 2)
bounced = Vector(-1 * vx, vy)
vel = bounced * 1.1
ball.velocity = vel.x, vel.y + offset
class PongBall(Widget):
velocity_x = NumericProperty(0)
velocity_y = NumericProperty(0)
velocity = ReferenceListProperty(velocity_x, velocity_y)
def move(self):
self.pos = Vector(*self.velocity) + self.pos
class PongGame(Widget):
ball = ObjectProperty(None)
player1 = ObjectProperty(None)
player2 = ObjectProperty(None)
def __init__(self, *args, **kwargs):
super(PongGame, self).__init__(*args, **kwargs)
Clock.schedule_interval(self.update, 1.0 / 60.0)
def serve_ball(self, vel=(4, 0)):
self.ball.center = self.center
self.ball.velocity = vel
def update(self, dt):
self.ball.move()
#bounce of paddles
self.player1.bounce_ball(self.ball)
self.player2.bounce_ball(self.ball)
#bounce ball off bottom or top
if (self.ball.y < self.y) or (self.ball.top > self.top):
self.ball.velocity_y *= -1
#went of to a side to score point?
if self.ball.x < self.x:
self.player2.score += 1
self.serve_ball(vel=(4, 0))
if self.ball.x > self.width:
self.player1.score += 1
self.serve_ball(vel=(-4, 0))
def on_touch_move(self, touch):
if touch.x < self.width / 3:
self.player1.center_y = touch.y
if touch.x > self.width - self.width / 3:
self.player2.center_y = touch.y
class Manager(ScreenManager):
pass
class GameApp(App):
def build(self):
self.load_kv('t6.kv')
return Manager(transition=WipeTransition())
if __name__ == '__main__':
GameApp().run()
and .kv is here...
<PongBall>:
size: 50, 50
canvas:
Ellipse:
pos: self.pos
size: self.size
<PongPaddle>:
size: 25, 200
canvas:
Rectangle:
pos:self.pos
size:self.size
<PongGame>:
ball: pong_ball
player1: player_left
player2: player_right
canvas:
Rectangle:
pos: self.center_x-5, 0
size: 10, self.height
Label:
font_size: 70
center_x: root.width / 4
top: root.top - 50
text: str(root.player1.score)
Label:
font_size: 70
center_x: root.width * 3 / 4
top: root.top - 50
text: str(root.player2.score)
PongBall:
id: pong_ball
center: self.parent.center
PongPaddle:
id: player_left
x: root.x
center_y: root.center_y
PongPaddle:
id: player_right
x: root.width-self.width
center_y: root.center_y
<Manager>:
id: screen_manager
Screen:
name: 'home'
Button:
text: 'Play Ping Pong'
halign: 'center'
valign: 'middle'
font_size: 100
text_size: self.size
on_release: root.current = 'game';game.serve_ball()
Screen:
name: 'game'
PongGame:
id: game
Hope this would help...

Categories

Resources