Home > Back-end >  AttributeError: 'MyMainApp' object has no attribute 'random_screen'
AttributeError: 'MyMainApp' object has no attribute 'random_screen'

Time:09-28

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 to MyMainApp (and get rid of TestApp),
  • or the other way around, make TestApp inherit from App and move the build method there, then use TestApp instead of MyMainApp.

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
  • Related