Python и Kivy: извлечение значения с другого экрана, чтобы установить значение кнопки on_release

#python #sqlite #kivy

#python #sqlite #kivy

Вопрос:

Хорошо, итак, к чему я стремлюсь, так это к тому, что когда вы нажимаете кнопку, скажем, на «Другом экране», я хочу, чтобы меня отправили на «Экран 0». Здесь, в зависимости от значения, которое равно 0 или 1, полученного из базы данных SQLite, кнопка «btn» на экране либо отправит вас на экран1 (если значение равно 0), либо на экран2, если значение не равно 0 (1). Однако при этом возникают некоторые ошибки.

Вот некоторый код, чтобы объяснить это лучше:

pythonfile.py

 import sql_server_file as app_users
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.app import App

class screen0(Screen):
    def __init__(self):
        self.sql_cursor = app_users.AppUsers()
        self.user_id = self.manager.get_screen("anotherScreen").user_id   # <---- This gives 
                                                                      # me an NoneType Error

        self.value = self.sql_cursor.fetch_ids100_done_status(self.user_id)
        if(self.value == 0):
            self.ids["btn"].on_release = "app.root.current = 'screen1'" # <---- This is 
                                          # syntactically wrong, however, how can I do this?

        else:
            self.ids["btn"].on_release = "app.root.current = 'screen2'" # <-- See above

class screen1(Screen):
    pass
class screen2(screen):
    pass
class anotherScreen(Screen):
    def __init__(self):
        self.user_id = 0

class WindowManager(ScreenManager):
    pass

class ReturnClass(App):
    def build(self):
        sm = ScreenManager()
        sm.add_widget(anotherScreen())
        sm.add_widget(screen0())
        sm.add_widget(screen1())
        sm.add_widget(screen2())
        return sm

if __name__ == '__main__':
    ReturnClass().run()
 

Итак, мне нужно, чтобы это запускалось «автоматически» при вводе экрана после «anotherScreen».

Ошибка:

 AttributeError: 'NoneType' object has no attribute 'get_screen'
 

файл kivy может выглядеть следующим образом:

kivyfile.kv

 WindowManager:
    anotherScreen:
    screen0:
    screen1:
    screen2:

<anotherScreen>:
    Button:
        text: "get to screen0"
        on_release:
            app.root.current = "screen0"

<screen0>:
    Button:
        text: "Get to either screen1 or screen2 depending on value in sqlite-database"

<screen1>:
    Label:
        text: "Screen1"

<screen2>:
    Label:
        text: "Screen2"
 

Ответ №1:

__init__() Метод screen0 вызывается до того, как он присваивается a ScreenManager , поэтому self.manager он есть None . Это вызывает ошибку, которую вы видите. Исправление заключается в перемещении этого кода в другой метод, который вызывается после ScreenManager назначения. Хорошим выбором будет on_enter() метод, который вызывается автоматически при вводе экрана.

Тогда screen0 класс может быть:

 class screen0(Screen):
    # no __init__() method needed

    def goto_screen1(self):   # go to screen1
        self.manager.current = 'screen1'

    def goto_screen2(self):   # go to screen2
        self.manager.current = 'screen2'

    def on_enter(self, *args)::   # the new method
        self.sql_cursor = app_users.AppUsers()
        self.user_id = self.manager.get_screen("anotherScreen").user_id

        self.value = self.sql_cursor.fetch_ids100_done_status(self.user_id)
        if(self.value == 0):
            self.ids["btn"].on_release = self.goto_screen1

        else:
            self.ids["btn"].on_release = self.goto_screen2
 

Обратите внимание, что Screen классы должны иметь name присвоенное значение.

Кроме того, строки в вашем kv :

 WindowManager:
    anotherScreen:
    screen0:
    screen1:
    screen2:
 

являются избыточными (поскольку вы создаете одно и то же дерево виджетов в своем build() методе) и могут быть удалены.

Комментарии:

1. Большое спасибо, Джон! Да, извините, я только что написал краткое изложение своей проблемы и забыл имена в kv-файле. Я не знал, что эти строки были избыточными, только начал изучать kivy! Это очень помогает, спасибо за ответ, и я надеюсь, что у вас будет хороший день!

2. Обратите внимание на мой отредактированный ответ с лучшим решением.

3. Хм, значит, метод on_enter вызывается автоматически?

4. Неважно, я нашел ответ в документах kivy. Ответ, очевидно, да! Большое спасибо за ответ.