如何在 Kivy、Kivy Lang、Kivy MD 中使用 ID 引用小部件内的小部件

问题描述

好吧,这让我像过去两天一样发疯。这真的很烦人,所以我正在使用 kivy 构建一个应用程序,在使用“像馅饼一样简单” tkinter 之后,我认为是时候学习 kivy(因为它具有移动兼容性)。

#我想学习引用不同的小部件# 我在 YouTube 和 google 上搜索了几个小时但无济于事 我不断收到错误消息

我的代码

.py

# Imports
import webbrowser
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen


# Todo: Monetizing the Application

def Monetize():
    pass


def hide():
    # hidden func thats not related to code for Now

# configuring the Application
class HyperSearch(App):
    main_text = "None"

    # initialing the Application
    def __init__(self,**kwargs):
        super(HyperSearch,self).__init__(**kwargs)
        self.a = Builder.load_file("kivy_file.kv")

    def get_search(self):
        engine_input = self.root.ids.raw_search

    # building the Application
    def build(self):
        screen = Screen()
        screen.add_widget(self.a)
        #  screen.add_widget("")
        return screen


# Running The Application in main loop
if __name__ == "__main__":
    HyperSearch().run()

# Todo: copyright Claim The Application and its code

.kv


    <HyperSearch>:
GridLayout:
    cols: 2
    BoxLayout:
        orientation: "vertical"
        size_hint: None,1
        size: "120dp",0
        spacing: 5

        Button:
            text: "Toggle Shopping Search"
            text_size: self.size
            halign: 'center'
            valign: 'middle'

        Button:
            text: "Toggle Music Search"
            text_size: self.size
            halign: 'center'
            valign: 'middle'

        Button:
            text: "View History"
            text_size: self.size
            halign: 'center'
            valign: 'middle'

    BoxLayout:
        orientation: "vertical"
        valign: "top"
        TextInput:
            valign: "center"
            orientation: "vertical"
            font_size: 30
            size_hint: 1,None
            size: 0,"50dp"
            pos_hint: {"top":1}
            hint_text: "Search-Engine"
            icon_right: "android"
            helper_text: "Devices with under 1gb RAM may crash"
            helper_text_mode: "on_focus"
            multiline: False
            id: raw_search



        GridLayout:
            cols: 2
            size_hint: 1,"100dp"
            spacing: 10
            Button:
                text: "Search!!"
                text_size: self.size
                halign: 'center'
                valign: 'middle'
                size_hint: .5,1
                on_press: app.get_search()
            Button:
                text: "Small Search :("
                text_size: self.size
                halign: 'center'
                valign: 'middle'
                size_hint: .5,1
        GridLayout:
            cols: 2
            size_hint: 1,"100dp"
            Label:
                text: "log:"

            Label:
                text: app.main_text

我的错误

   
[INFO   ] [Base        ] Start application main loop
[INFO   ] [Base        ] Leaving application in progress...
 Traceback (most recent call last):
   File "kivy\properties.pyx",line 861,in kivy.properties.ObservableDict.__getattr__
 KeyError: 'raw_search'
 
 During handling of the above exception,another exception occurred:
 
 Traceback (most recent call last):
   File "C:\documents\kivy-trial\main.py",line 63,in <module>
     HyperSearch().run()
   File "C:\Users\mayan\AppData\Local\Programs\Python\python39\lib\site-packages\kivy\app.py",line 950,in run
     runTouchApp()
   File "C:\Users\mayan\AppData\Local\Programs\Python\python39\lib\site-packages\kivy\base.py",line 582,in runTouchApp
     EventLoop.mainloop()
   File "C:\Users\mayan\AppData\Local\Programs\Python\python39\lib\site-packages\kivy\base.py",line 347,in mainloop
     self.idle()
   File "C:\Users\mayan\AppData\Local\Programs\Python\python39\lib\site-packages\kivy\base.py",line 391,in idle
     self.dispatch_input()
   File "C:\Users\mayan\AppData\Local\Programs\Python\python39\lib\site-packages\kivy\base.py",line 342,in dispatch_input
     post_dispatch_input(*pop(0))
   File "C:\Users\mayan\AppData\Local\Programs\Python\python39\lib\site-packages\kivy\base.py",line 248,in post_dispatch_input
     listener.dispatch('on_motion',etype,me)
   File "kivy\_event.pyx",line 709,in kivy._event.Eventdispatcher.dispatch
   File "C:\Users\mayan\AppData\Local\Programs\Python\python39\lib\site-packages\kivy\core\window\__init__.py",line 1412,in on_motion
     self.dispatch('on_touch_down',line 1428,in on_touch_down
     if w.dispatch('on_touch_down',touch):
   File "kivy\_event.pyx",in kivy._event.Eventdispatcher.dispatch
   File "C:\Users\mayan\AppData\Local\Programs\Python\python39\lib\site-packages\kivy\uix\relativelayout.py",line 297,in on_touch_down
     ret = super(RelativeLayout,self).on_touch_down(touch)
   File "C:\Users\mayan\AppData\Local\Programs\Python\python39\lib\site-packages\kivy\uix\widget.py",line 545,in on_touch_down
     if child.dispatch('on_touch_down',in kivy._event.Eventdispatcher.dispatch
   File "C:\Users\mayan\AppData\Local\Programs\Python\python39\lib\site-packages\kivy\uix\widget.py",in kivy._event.Eventdispatcher.dispatch
   File "C:\Users\mayan\AppData\Local\Programs\Python\python39\lib\site-packages\kivy\uix\behaviors\button.py",line 151,in on_touch_down
     self.dispatch('on_press')
   File "kivy\_event.pyx",line 705,in kivy._event.Eventdispatcher.dispatch
   File "kivy\_event.pyx",line 1248,in kivy._event.EventObservers.dispatch
   File "kivy\_event.pyx",line 1132,in kivy._event.EventObservers._dispatch
   File "C:\Users\mayan\AppData\Local\Programs\Python\python39\lib\site-packages\kivy\lang\builder.py",line 57,in custom_callback
     exec(__kvlang__.co_value,idmap)
   File "C:\Documents\kivy-trial\kivy_file.kv",line 58,in <module>
     on_press: app.get_search()
   File "C:\documents\kivy-trial\main.py",line 51,in get_search
     engine_input = self.root.ids.raw_search
   File "kivy\properties.pyx",line 864,in kivy.properties.ObservableDict.__getattr__
 AttributeError: 'super' object has no attribute '__getattr__'

Process finished with exit code 1

P.S:错误仅在我按下按钮后显示

请帮助,在此先感谢那些花时间阅读我的帖子的人

解决方法

让我们举一个简单的例子来说明如何使用 kivy 的魔法 id 属性!

from kivy.lang import Builder
from kivymd.app import MDApp

KV = '''
BoxLayout:
    Button:
        id: my_button
        text: "let's try !"
'''

class MyApp(MDApp):
    def build(self):
        self.screen = Builder.load_string(KV)
        print("this is the app:",self)
        print("this is the visual of the app:",self.screen)
        print("this is the dictionnary of all object referenced with id in the app KV:",self.screen.ids)
        print("this is my button:",self.screen.ids["my_button"])

        print("let's bind a function to my button referenced in the KV object")
        self.screen.ids["my_button"].bind(on_press=self.on_button_press)
        return self.screen

    def on_button_press(self,instance):
        print("this is the widget linked to this event call (here it's the button):",instance)
        print("here you can do whatever you want,yes kivy is easy !")


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

如果有什么不清楚的地方或者我错过了问题,请不要犹豫提问:)

PS:如果你想使用 .kv 文件,它会以同样的方式工作!只需将 Builder.load_string(KV) 替换为 Builder.load_file("kivy_file.kv")。 你已经做得很好,我只想说它不会改变任何东西。 ;)

,

为了使用 ids,您必须在 id 中定义 kv。因此,要使用 raw_search id,您必须像这样在 kv 中定义它:

    TextInput:
        id: raw_search

然后在您的代码中:

def get_search(self):
    engine_input = self.a.ids.raw_search.text
    print(engine_input)

请注意,ids 字典是在作为包含 id 的规则的根的小部件中构建的。在您的情况下,idsGridLayout 中。因此,要访问该 GridLayout 小部件,您必须使用 self.a。此外,我认为您的 <HyperSearch>: 中的 kv 行是一个拼写错误并已将其删除。