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

2024-09-28 18:49:21 发布

您现在位置:Python中文网/ 问答频道 /正文

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

#我想学习引用不同的小部件# 我在YouTube和谷歌上搜索了几个小时,但都没有结果 我一直收到一条错误消息

我的代码:

.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, None
            size: 0, "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, None
            size: 0, "100dp"
            Label:
                text: "log:"

            Label:
                text: app.main_text

my error

   
[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', 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 1428, in on_touch_down
     if w.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 709, 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', touch):
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   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', touch):
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   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', touch):
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   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', touch):
   File "kivy\_event.pyx", line 709, 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:只有在我按下按钮后才会显示错误

请帮助我,提前感谢曾经花时间阅读我帖子的人


Tags: textinpyselfeventsizeonline
2条回答

为了使用ids,必须在kv中定义id。因此,要使用raw_search{},必须在kv中定义它,如下所示:

    TextInput:
        id: raw_search

然后在代码中:

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

注意ids字典是在小部件中构建的,该小部件是包含id的规则的根。在您的例子中,ids位于GridLayout中。因此,要访问GridLayout小部件,必须使用self.a。另外,我假设您的kv中的<HyperSearch>:行是一个拼写错误,并将其删除

让我们给你一个简单的例子来说明如何使用kivy的magicid属性

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_file("kivy_file.kv")替换Builder.load_string(KV)。 你已经做得很好了,我只想说这不会改变任何事情

相关问题 更多 >