Hiii ^_^.
I am a beginner in python and kivy and I decided to learn by building an application with registration and login after which it will transfer me to the game. The game is based on images displayed through ScreenManager. All good so far. The code for the interface with menu, registration and logging is in another project and the one with the game in another, so I decided to combine them, I mostly succeeded but I got stuck at the step where it sends me to the first screen of the game and from there pressing a button to generate a Screen randomly I get this error ~~ AttributeError: 'MyMainApp' object has no attribute 'random_screen' ~~
I have tried all kinds of solutions to solve this problem, but I can't figure it out in any way. Can someone tell me where I am wrong? If I add the code lines with random_screen in the MyMainApp class, nothing happens..
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from database import DataBase
import random
class CreateAccountWindow(Screen):
namee = ObjectProperty(None)
email = ObjectProperty(None)
password = ObjectProperty(None)
def submit(self):
if self.namee.text != "" and self.email.text != "" and self.email.text.count("@") == 1 and self.email.text.count(".") > 0:
if self.password != "":
db.add_user(self.email.text, self.password.text, self.namee.text)
self.reset()
sm.current = "login"
else:
invalidForm()
else:
invalidForm()
def login(self):
self.reset()
sm.current = "login"
def reset(self):
self.email.text = ""
self.password.text = ""
self.namee.text = ""
class LoginWindow(Screen):
email = ObjectProperty(None)
password = ObjectProperty(None)
def loginBtn(self):
if db.validate(self.email.text, self.password.text):
MainWindow.current = self.email.text
self.reset()
sm.current = "main"
else:
invalidLogin()
def createBtn(self):
self.reset()
sm.current = "create"
def reset(self):
self.email.text = ""
self.password.text = ""
class MainWindow(Screen):
n = ObjectProperty(None)
created = ObjectProperty(None)
email = ObjectProperty(None)
current = ""
def logOut(self):
sm.current = "login"
class Q1(Screen):
pass
class Q2(Screen):
pass
class Q3(Screen):
pass
class Q4(Screen):
pass
class WrongAnswer(Screen):
pass
class TestApp:
def wrong_answer(self):
screen = ['WrongAnswer']
return random.choice(screen)
def random_screen(self):
screens = ['Q1', 'Q2', 'Q3', 'Q4']
return random.choice(screens)
def build(self):
sm = ScreenManager()
sm.add_widget(Q1(name='Q1'))
sm.add_widget(Q2(name='Q2'))
sm.add_widget(Q3(name='Q3'))
sm.add_widget(Q4(name='Q4'))
sm.add_widget(WrongAnswer(name='WrongAnswer'))
return sm
class WindowManager(ScreenManager):
pass
def invalidLogin():
pop = Popup(title='Invalid Login',
content=Label(text='Invalid username or password.'),
size_hint=(None, None), size=(400, 400))
pop.open()
def invalidForm():
pop = Popup(title='Invalid Form',
content=Label(text='Please fill in all inputs with valid information.'),
size_hint=(None, None), size=(400, 400))
pop.open()
kv = Builder.load_file("my.kv")
sm = WindowManager()
db = DataBase("users.txt")
screens = [LoginWindow(name="login"), CreateAccountWindow(name="create"),MainWindow(name="main"),Q1(name="start")]
for screen in screens:
sm.add_widget(screen)
sm.current = "login"
class MyMainApp(App):
def build(self):
return sm
if __name__ == "__main__":
MyMainApp().run()
<CreateAccountWindow>:
name: "create"
namee: namee
email: email
password: passw
FloatLayout:
cols:1
FloatLayout:
size: root.width, root.height/2
Label:
text: "Create an Account"
size_hint: 0.8, 0.2
pos_hint: {"x":0.16, "top":1}
font_size: (root.width**2 root.height**2) / 14**4
Label:
size_hint: 0.5,0.12
pos_hint: {"x":0, "top":0.8}
text: "Name: "
font_size: (root.width**2 root.height**2) / 14**4
TextInput:
pos_hint: {"x": 0.38, "top":0.77}
size_hint: 0.4, 0.075
id: namee
multiline: False
font_size: (root.width**2 root.height**2) / 14**4
Label:
size_hint: 0.5,0.12
pos_hint: {"x":0, "top":0.8-0.13}
text: "E-Mail: "
font_size: (root.width**2 root.height**2) / 14**4
TextInput:
pos_hint: {"x": 0.38, "top":0.65}
size_hint: 0.4, 0.075
id: email
multiline: False
font_size: (root.width**2 root.height**2) / 14**4
Label:
size_hint: 0.5,0.12
pos_hint: {"x":0, "top":0.8-0.125*2}
text: "Password: "
font_size: (root.width**2 root.height**2) / 14**4
TextInput:
pos_hint: {"x": 0.38, "top":0.53}
size_hint: 0.4, 0.075
id: passw
multiline: False
password: True
font_size: (root.width**2 root.height**2) / 14**4
Button:
pos_hint:{"x":0.60,"y":0.35}
size_hint: 0.18, 0.075
font_size: (root.width**2.11 root.height**2) / 17**4
text: "Back to Login"
on_release:
root.manager.transition.direction = "left"
root.login()
Button:
pos_hint:{"x":0.38,"y":0.35}
size_hint: 0.18, 0.075
text: "Register"
font_size: (root.width**1.95 root.height**2) / 14**4
on_release:
root.manager.transition.direction = "left"
root.submit()
<LoginWindow>:
name: "login"
email: email
password: password
FloatLayout:
Label:
text:"E-Mail: "
font_size: (root.width**1.8 root.height**2) / 13**4
pos_hint: {"x":0.1, "top":0.9}
size_hint: 0.40, 0.15
TextInput:
id: email
font_size: (root.width**1.91 root.height**2) / 13**4
multiline: False
pos_hint: {"x": 0.38 , "top":0.86}
size_hint: 0.4, 0.075
Label:
text:"Password: "
font_size: (root.width**1.8 root.height**2) / 13**4
pos_hint: {"x":0.106, "top":0.81}
size_hint: 0.35, 0.15
TextInput:
id: password
font_size: (root.width**1.91 root.height**2) / 13**4
multiline: False
password: True
pos_hint: {"x": 0.38, "top":0.77}
size_hint: 0.4, 0.075
Button:
pos_hint:{"x":0.38,"y":0.605}
size_hint: 0.18, 0.075
font_size: (root.width**1.8 root.height**2) / 13**4
text: "Login"
on_release:
root.manager.transition.direction = "up"
root.loginBtn()
Button:
pos_hint:{"x":0.60,"y":0.605}
size_hint: 0.18, 0.075
font_size: (root.width**2.09 root.height**2) / 17**4
text: "Create Account"
on_release:
root.manager.transition.direction = "right"
root.createBtn()
<MainWindow>:
FloatLayout:
Button:
pos_hint:{"x": 0.6, "top":0.9}
size_hint:0.4, 0.1
text: "5 Players"
Button:
pos_hint:{"x": 0.6, "top":0.7}
size_hint:0.4, 0.1
text: "10 Players"
Button:
pos_hint:{"x": 0.6, "top":0.5}
size_hint:0.4, 0.1
text: "15 Players"
Button:
pos_hint:{"x": 0.6, "top":0.3}
size_hint:0.4, 0.1
text: "20 Players"
on_release:
app.root.current = "start"
root.manager.transition.direction = "down"
Button:
pos_hint:{"x":0.04, "y": 0.05}
size_hint:0.2,0.1
text: "Log Out"
on_release:
app.root.current = "login"
root.manager.transition.direction = "down"
<Q1>:
name: "start"
Image:
source: 'Q1.png'
FloatLayout:
size: root.width, root.height/2
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.random_screen()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
<Q2>:
Image:
source: 'Q2.png'
FloatLayout:
size: root.width, root.height/2
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.random_screen()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
<Q3>:
Image:
source: 'Q3.png'
FloatLayout:
size: root.width, root.height/2
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.random_screen()
<Q4>:
Image:
source: 'Q4.png'
FloatLayout:
size: root.width, root.height/2
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.random_screen()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
<WrongAnswer>:
Image:
source: 'L1.png'
CodePudding user response:
Your random_screen
function is in TestApp
, which you don't use for anything. Instead, your app seems to be MyMainApp
.
You can
- move the contents of
TestApp
toMyMainApp
(and get rid ofTestApp
), - or the other way around, make
TestApp
inherit fromApp
and move thebuild
method there, then useTestApp
instead ofMyMainApp
.
CodePudding user response:
You already knew what is the cause. in mymainapp class, you don't have the attirube: random_screen. random_screen is in class TestApp. if you want that attribute exist in mymainapp class, you can use multiple inherit. like this:
class MyMainApp(App, TestApp):
def build(self):
return sm