Python - Kivy - on_enter - 无法在屏幕中处理小部件

Python - Kivy - on_enter - Cannot address widget in Screen

我试图在下面的代码中显示屏幕后立即隐藏进度条。但是它给出了“AttributeError: 'super' object has no attribute 'getattr'”错误。

我尝试调试代码,我看到的是当在 on_event 中调用 self 时,它无法将自己定位到“win_Main”屏幕,因此 self 的 ID 不起作用。

在表单打开之前处理进度条的正确方法是什么? 提前致谢...

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window

f_path = ""
wbk = ""

dsg_main_height = 460   # dsg: Design Related Variables
dsg_image_ratio = 0.12


class MyWinMan(ScreenManager):
    pass


class W_MainMenu(Screen):

    def on_enter(self):
        self.hide_widget(self.ids.pgb_sql_read, True)

    def hide_widget(self, wid, dohide=True):
        
        if hasattr(wid, 'saved_attrs'):
            if not dohide:
                wid.height, wid.size_hint_y, wid.opacity, wid.disabled = wid.saved_attrs
                del wid.saved_attrs
        elif dohide:
            wid.saved_attrs = wid.height, wid.size_hint_y, wid.opacity, wid.disabled
            wid.height, wid.size_hint_y, wid.opacity, wid.disabled = 0, None, 0, True

    def transform_to_filechooser(self):
        pass
        
    def import_to_sql(self):
       pass

class W_FileSelector(Screen):
    pass


Builder.load_string("""


MyWinMan:

    W_MainMenu:
    W_FileSelector:

<W_MainMenu>:
    
    name:           "win_Main"

    BoxLayout:

        orientation:    "vertical"
        size:           root.width, root.height
        padding:        40
        spacing:        10

        Button:
            text:       'Browse for Source Excel File'
            font_size:  20
            on_release: 
                app.root.current = "win_FS"
                root.manager.transition.direction = "up"
                root.transform_to_filechooser()

        ProgressBar:
            id:         pgb_sql_read
            min:        0
            max:        100
            value:      0
            size_hint:  ( 1, 0.1)

            
<W_FileSelector>:
    
    name:   "win_FS"
    id:     my_widget

    BoxLayout:

        orientation: 
            "vertical"
        size:       root.width, root.height
        padding:    50
        spacing:    20

        Label:
            text:       'Please select the file...'
            size_hint:  ( 1, 0.1)
            font_size:  20

""")


Window.size = (700, dsg_main_height)
Window.top = 50
Window.left = 100

class MyApp(App):

    def build(self):
        return W_MainMenu()


if __name__ == '__main__':

    MyApp().run()

问题是在声明 rootkvlang 中的 id 尚未创建。解决这个问题的一种方法是在 on_enter 方法中设置条件语句超过 idProgressBar 小部件(通过创建对它的引用)。

你可以这样做:

  1. 如果您不想为 ProgressBar 创建一个引用(或者您不需要),下面的方法也可行(但可能不是一个优雅的方法)。
class W_MainMenu(Screen):

    def on_enter(self):
        # First check whether or not the ids are created, if yes perform the action.
        if self.ids:
            self.hide_widget(self.ids.pgb_sql_read, True)

  1. 或者为 ProgressBar 创建一个引用。
class W_MainMenu(Screen):
    prog_bar = ObjectProperty(None)

    def on_enter(self):
        # First check whether or not the ProgressBar is loaded, if yes perform the action.

        if self.prog_bar:
            self.hide_widget(self.ids.pgb_sql_read, True)

现在将 kvlang 中的 ProgressBar 称为

<W_MainMenu>:
    prog_bar: pgb_sql_read
    
    name:           "win_Main"

    BoxLayout:

作为旁注(如评论中所述),您可以将方法 build 中已创建的 root(在 kvlang 中)声明为

    def build(self):
        return Builder.load_string(kv)

其中 'kv' 是字符串,

kv = ("""

MyWinMan:

    W_MainMenu:
    W_FileSelector:

<W_MainMenu>:
    prog_bar: pgb_sql_read
    
.
.
.

""")

更新:

以上回答试图解决您在问题中提到的内容,即 'Python - Kivy - on_enter - Cannot address widget in Screen'.

如果您想让 ProgressBar 在应用程序启动时消失(但也许稍后会重新出现),您可以在 kvlang 内通过使用特定标志设置某些条件来实现。

在您的 class W_MainMenu,

中排名第一
class W_MainMenu(Screen):
    hide_progress = BooleanProperty(True)

然后在其设计内 kvlang,

        ProgressBar:
            id: pgb_sql_read
            min: 0
            max: 100
            value: 0
            size_hint: (1, None) if root.hide_progress else (1, 0.1)
            height: 0 if root.hide_progress else self.height
            disabled: root.hide_progress
            opacity: int(not root.hide_progress)

现在,也许您想让它再次出现(在这种情况下,我在您的屏幕 W_FileSelector 中添加了一个额外的 Button 以触发该事件)。

...
        Label:
            text: 'Please select the file...'
            size_hint:  ( 1, 0.1)
            font_size:  20

        Button:
            text: "Go to main page"
            on_release: 
                app.root.current = "win_Main"
                app.root.current_screen.hide_progress = False
...