如何正确使用.kv文件和.py? - 从 .kv 调用函数如何构建 .py

Posted

技术标签:

【中文标题】如何正确使用.kv文件和.py? - 从 .kv 调用函数如何构建 .py【英文标题】:how to use the .kv file and .py properly? - calling functions from .kv how to structure .py 【发布时间】:2020-11-09 03:25:35 【问题描述】:

试图理解kivy。

处理涉及几个屏幕的简单应用程序。目前,我正在尝试从...中的按钮 on_release 调用弹出窗口,但没有成功。 错误:

 Traceback (most recent call last):
   File "C:\Users\thoma\PycharmProjects\FacesApp\venv\lib\site-packages\kivy\lang\builder.py", line 725, in _apply_rule
     raise AttributeError(key)
 AttributeError: release
 
 During handling of the above exception, another exception occurred:
 
 Traceback (most recent call last):
   File "C:/Users/thoma/PycharmProjects/FacesGUI/main.py", line 36, in <module>
     kv = Builder.load_file("my.kv")
   File "C:\Users\thoma\PycharmProjects\FacesApp\venv\lib\site-packages\kivy\lang\builder.py", line 301, in load_file
     return self.load_string(data, **kwargs)
   File "C:\Users\thoma\PycharmProjects\FacesApp\venv\lib\site-packages\kivy\lang\builder.py", line 405, in load_string
     rule_children=rule_children)
   File "C:\Users\thoma\PycharmProjects\FacesApp\venv\lib\site-packages\kivy\lang\builder.py", line 657, in _apply_rule
     root=rctx['ids']['root'], rule_children=rule_children)
   File "C:\Users\thoma\PycharmProjects\FacesApp\venv\lib\site-packages\kivy\uix\widget.py", line 469, in apply_class_lang_rules
     rule_children=rule_children)
   File "C:\Users\thoma\PycharmProjects\FacesApp\venv\lib\site-packages\kivy\lang\builder.py", line 538, in apply
     rule_children=rule_children)
   File "C:\Users\thoma\PycharmProjects\FacesApp\venv\lib\site-packages\kivy\lang\builder.py", line 734, in _apply_rule
     ': '.format(e.__class__.__name__, e), cause=tb)
 kivy.lang.builder.BuilderException: Parser: File "C:\Users\thoma\PycharmProjects\FacesGUI\my.kv", line 100:
 ...
      98:                    center_x: self.parent.center_x
      99:                    center_y: self.parent.center_y
 >>  100:                    on_release: root.show_popup()
     101:
     102:
 ...
 AttributeError: release
   File "C:\Users\thoma\PycharmProjects\FacesApp\venv\lib\site-packages\kivy\lang\builder.py", line 725, in _apply_rule
     raise AttributeError(key)

我尝试使用 root、app、self 调用并创建 MyMainApp() 的实例并将其传入。????????

我注意到一些用户建议在 .py 中使用构建器字符串,而其他用户建议使用 .kv 文件进行布局等。

其中一个有什么优点或缺点..?虽然我习惯于为逻辑使用 xml 布局和 java/kotlin 类,但使用 .kv 有点……令人困惑。

我的.kv

<P>:
    Label:
        text: "Eneter Name or Type 'skip':"

    TextInput:
        text: ""

    Button:
        text: "Submit"




WindowManager:
    MainWindow:
    SecondWindow:

<MainWindow>:
    name: "main"

    GridLayout:
        cols:2


        Button:
            text:"Live Camera"
            on_press: root.activatecamera()

        Button:
            text:"SD Card"
            on_press: root.sdcard()

        Button:
            text:"Event Images"
            on_press: root.viewEventImages()

        Button:
            text:"Event Faces"
            on_release:
                app.root.current = "eventfaces"
                root.manager.transition.direction = "left"

        Button:
            text:"List Names"
            on_press: root.listknownfaces()

        Button:
            text:"View Log"
            on_press: root.pipeout()

        Button:
            text:"Scan Directory"
            on_press: root.scanDirectory()

        Button:
            text:"Facial Recognition on Image"
            on_press: root.metadataRead()


        Button:
            text:"Label Image"
            on_press: root.metadataRead()



        Button:
            text:"Blur Faces"
            on_press: root.metadataRead()

        Button:
            text: "Metadata"
            on_release:
                app.root.current = "second" if passw.text == "tim" else "main"
                root.manager.transition.direction = "left"

        Button:
            text: "Misc."
            on_release:
                app.root.current = "second" if passw.text == "tim" else "main"
                root.manager.transition.direction = "left"


<SecondWindow>:
    name: "eventfaces"


    GridLayout:
        cols:1
        rows:2

        GridLayout:
            cols:4

            Button:
                id: myButton
                Image:
                    source: "unnamed/unnamed1.jpg"
                    center_x: self.parent.center_x
                    center_y: self.parent.center_y
                    on_release: root.show_popup()


            Button:
                id: myButton
                Image:
                    source: "unnamed/unnamed2.jpg"
                    center_x: self.parent.center_x
                    center_y: self.parent.center_y


            Button:
                id: myButton
                Image:
                    source: "unnamed/unnamed3.jpg"
                    center_x: self.parent.center_x
                    center_y: self.parent.center_y

            Button:
                id: myButton
                Image:
                    source: "unnamed/unnamed4.jpg"
                    center_x: self.parent.center_x
                    center_y: self.parent.center_y


            Button:
                id: myButton
                Image:
                    source: "unnamed/unnamed5.jpg"
                    center_x: self.parent.center_x
                    center_y: self.parent.center_y

            Button:
                id: myButton
                Image:
                    source: "unnamed/unnamed6.jpg"
                    center_x: self.parent.center_x
                    center_y: self.parent.center_y


            Button:
                id: myButton
                Image:
                    source: "unnamed/unnamed7.jpg"
                    center_x: self.parent.center_x
                    center_y: self.parent.center_y

            Button:
                id: myButton
                Image:
                    source: "unnamed/unnamed8.jpg"
                    center_x: self.parent.center_x
                    center_y: self.parent.center_y

            Button:
                id: myButton
                Image:
                    source: "unnamed/unnamed9.jpg"
                    center_x: self.parent.center_x
                    center_y: self.parent.center_y

            Button:
                id: myButton
                Image:
                    source: "unnamed/unnamed10.jpg"
                    center_x: self.parent.center_x
                    center_y: self.parent.center_y

            Button:
                id: myButton
                Image:
                    source: "unnamed/unnamed11.jpg"
                    center_x: self.parent.center_x
                    center_y: self.parent.center_y



            Button:
                text: "Main Menu"
                on_release:
                    app.root.current = "main"
                    root.manager.transition.direction = "left"

main.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.popup import Popup


class P(BoxLayout):
    pass


class MainWindow(Screen):
    pass


class SecondWindow(Screen):
    pass


class WindowManager(ScreenManager):
    pass


def show_popup():
    show = P()  # Create a new instance of the P class

    popupWindow = Popup(title="Enter Name or Type 'skip': ", content=show, size_hint=(None, None), size=(400, 400))
    # Create the popup window

    popupWindow.open()  # show the popup


kv = Builder.load_file("my.kv")


class MyMainApp(App):
    def build(self):
        return kv


if __name__ == "__main__":
    MyMainApp().run()

如果有人可以指导我是否应该使用 Builder 字符串进程或 .kv 和/或如何创建一个带有标签、文本输入和按钮的弹出窗口并从其中的按钮调用,我将不胜感激。

我认为我的 .py 文件存在关于结构的错误。正如我在示例中看到的那样,我尝试将 def show_popup() 移动到 SecondWindow 类中,但没有成功。

是否需要将定义分配给每个窗口?还是可以从窗口类外部调用它们?

提前致谢。我知道它对于一个简单的任务来说很长。 :/

【问题讨论】:

代码运行如果 on_release: root.show_popup() 被注释掉 【参考方案1】:

Image 不支持 on_release: 参数。你需要把它移到Button:

        Button:
            id: myButton
            on_release: root.show_popup()
            Image:
                source: "unnamed/unnamed1.jpg"
                center_x: self.parent.center_x
                center_y: self.parent.center_y

另外,请注意id 只能引用一个Widget,因此myButton id 只会引用最后一个Buttonid

【讨论】:

谢谢!当我阅读您的帖子时,这似乎很明显......:?再次感谢。 知道为什么弹出内容会显示两次......即 2 x 文本输入和 2 x 按钮? .kv 中只有一个实例

以上是关于如何正确使用.kv文件和.py? - 从 .kv 调用函数如何构建 .py的主要内容,如果未能解决你的问题,请参考以下文章

如何编译具有 .kv 文件和其他资源文件的 .py 文件

kivy 对 .py 和 .kv 文件的需求是啥

如何打印在.kv(kivy)中输入的TextInput值,以打印在.py文件中?

我可以从 Python 触发在 KV 文件中创建的屏幕吗?

如何使用 .kv 文件在 kivy 中创建下拉列表

如何:main.py,带有 kivy 轮播代码的新类,kv 文件