Ошибка кивы при попытке сменить экран - PullRequest
0 голосов
/ 11 января 2020

Я не хотел использовать язык .kv. Так что моя проблема возникает при попытке запустить функцию, когда я нажимаю кнопку.
Я нашел эти вопросы, которые имели ту же проблему, поэтому я принял код для метода on_press из них:
kivy python передача параметров в fuction нажатием кнопки
Python, Kivy, «AssertionError: None not callable» Ошибка при вызове функции кнопкой

Ошибка

File "kivy\_event.pyx", line 703, in kivy._event.EventDispatcher.dispatch
   File "kivy\_event.pyx", line 1214, in kivy._event.EventObservers.dispatch
   File "kivy\_event.pyx", line 1138, in kivy._event.EventObservers._dispatch
   File "C:\Users\schup\PycharmProjects\Workspace\kivy_app_go\Surface.py", line 28, in <lambda>
     btnHvH = Button(text="Human vs Human", size_hint=(0.35, 0.15), on_release=lambda *args: self.HelperMethodsInst.switch_screen(goal_screen="go_screen", Screenmanager=WindowManager.get_ScreenManager, *args))
 TypeError: switch_screen() got multiple values for argument 'Screenmanager'

Surface.py:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy_app_go.Control import HelperMethods
from kivy.properties import ObjectProperty
from kivy.graphics import Rectangle, Color, Line
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.core.window import Window
from kivy.uix.screenmanager import FadeTransition

from functools import partial


class MenuScreen(Screen):
    def __init__(self, **kwargs):
        super(Screen, self).__init__(**kwargs)
        self.ScreenSize = Window.size
        self.HelperMethodsInst = HelperMethods()

        lytmain = FloatLayout(size=self.ScreenSize)
        lytbutton = BoxLayout(pos_hint={"y": 0.1, "x": 0.15}, size_hint=(2, 0.6), orientation='vertical', size=self.ScreenSize)

        lblHeadline = Label(text="Choose your Go Mode", font_size=40, pos_hint={"y": 0.8, "x": 0.325},
                            size_hint=(0.35, 0.15))
        btnHvH = Button(text="Human vs Human", size_hint=(0.35, 0.15), on_release=lambda *args: self.HelperMethodsInst.switch_screen(goal_screen="go_screen", Screenmanager=WindowManager.get_ScreenManager, *args))
        btnHvB = Button(text="Human vs Bot", size_hint=(0.35, 0.15), on_release=lambda *args: self.HelperMethodsInst.switch_screen(goal_screen="go_screen", Screenmanager=WindowManager.get_ScreenManager, *args))
        btnBvB = Button(text="Bot vs Bot", size_hint=(0.35, 0.15), on_release=lambda *args: self.HelperMethodsInst.switch_screen(goal_screen="go_screen", Screenmanager=WindowManager.get_ScreenManager, *args))

        self.add_widget(lytmain)
        lytmain.add_widget(lblHeadline)
        lytmain.add_widget(lytbutton)
        lytbutton.add_widget(btnHvH)
        lytbutton.add_widget(btnHvB)
        lytbutton.add_widget(btnBvB)



class GoScreen(Screen):
    def __init__(self, **kwargs):
        super(GoScreen, self).__init__(**kwargs)
        self.ScreenSize = Window.size

        lytmain = FloatLayout(size=self.ScreenSize)

        btnBack = Button(text="Back", size_hint=(0.25, 0.1))

        self.add_widget(lytmain)
        lytmain.add_widget(btnBack)


class WindowManager(ScreenManager):
    def __init__(self):
        self.sm = ScreenManager(transition=FadeTransition(duration=0.15))
        self.sm.add_widget(MenuScreen(name="menu_screen"))
        self.sm.add_widget(GoScreen(name="go_screen"))

    @property
    def get_ScreenManager(self):
        return self.sm

class Surface(App):
    def __init__(self):
        super().__init__()
        self.WindowManagerInst = WindowManager()

    def build(self):
        return self.WindowManagerInst.sm

    @staticmethod
    def create_Surface():
        return Surface().run()


def run():
    SurfaceInst = Surface()
    HelperMethodsInst = HelperMethods()



Control.py:

from kivy.uix.screenmanager import ScreenManager, Screen


class HelperMethods:
    def switch_screen(self, Screenmanager, goal_screen):
        screenmanager = goal_screen

main.py:

from kivy_app_go.Surface import Surface

if __name__ == "__main__":
    Surface.create_Surface()

Я новичок в kivy.
Я надеюсь, что кто-то может помочь ^^

1 Ответ

1 голос
/ 12 января 2020

Вы получаете

несколько значений для аргумента 'Screenmanager'

ошибка, поскольку ваш lambda создает функцию с аргументами ключевого слова, за которыми следует *args , Поскольку позиционные аргументы должны предшествовать ключевым словам, ваш *args рассматривается как часть ключевого слова Screenmanager=. Таким образом, это ключевое слово передается в ваш метод switch_screen как

Screenmanager = WindowManager.get_ScreenManager, *args

Если вам нужен экземпляр Button (то есть, что такое *args), переданный в ваш метод switch_screen, тогда вам нужно изменить этот метод, чтобы принять его (и настроить лямбду).

Вы можете избежать ошибки, просто удалив *args из конца lambda.

Однако, есть Еще одна проблема в той же строке кода. Вы используете WindowManager.get_ScreenManager, но WindowManager является классом, а не экземпляром, а в файле класса get_ScreenManager является свойством. Поэтому вам нужен экземпляр WindowManager, который вы можете получить из атрибута WindowManagerInst App. Таким образом, эта строка теперь становится: (вместе с вызовом для получения текущей App):

app = App.get_running_app()
btnHvH = Button(text="Human vs Human", size_hint=(0.35, 0.15), on_release=lambda *args: self.HelperMethodsInst.switch_screen(goal_screen="go_screen", Screenmanager=app.WindowManagerInst.get_ScreenManager))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...