【问题标题】:Understanding __init__() and Kivy's build() methods理解 __init__() 和 Kivy\'s build() 方法
【发布时间】:2022-09-23 00:07:11
【问题描述】:

你好,我是 python 和 kivy 的新手,也是在 Stackoverflow 上发帖的新手,所以如果我使用的术语不正确或出现任何其他错误编码风格,请纠正我。

我使用 kivy 和 python 创建了一个 GUI。一切正常,直到我在 GUI 中插入 DropDown。按照 Kivy Programming guide 上提供的示例,我创建了一个下拉列表,在 .kv 文件和 python 文件中实现它。

现在的问题是,当我运行应用程序时,下拉列表不显示。正如您在我的 Python 代码中看到的那样,我尝试使用方法 ControlsView().add_widget()mainbutton 添加到 ControlsView 布局,但没有运气。

然后我尝试将它放在应用程序的build() 方法中,如下所示:


def build():
    ControlsView().add_widget(mainbutton)
    return InteractiveGUI()

但也没有运气。

错误消息说:

文件“logicPortable.py”,第 38 行,在构建中 ControlsView.add_widget(mainbutton) TypeError: add_widget() 缺少 1 个必需的位置参数:\'widget\'

这是我的代码:

蟒蛇文件:


import kivy
kivy.require(\'2.1.0\')
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.dropdown import DropDown
from kivy.lang import Builder

Builder.load_file(\'GUI.kv\')

class InteractiveGUI(BoxLayout):
    pass

class CameraView(RelativeLayout):
    pass

class ControlsView(RelativeLayout):
    pass

class CameraDropDown(DropDown):
    pass

camera_select = CameraDropDown()
mainbutton = Button(text=\'Select Camera\',
                    size_hint_x=.7,
                    size_hint_y=None,
                    height=35,
                    pos_hint={\'center_x\': .5, \'center_y\': .5}
                    )
mainbutton.bind(on_release=camera_select.open)
camera_select.bind(on_select=lambda instance,x: setattr(mainbutton, \'text\', x))

ControlsView().add_widget(mainbutton)

class LogPortGUI(App):
    def build(self):
        return InteractiveGUI()

if __name__ == \'__main__\':
    LogPortGUI().run()

.kv 文件:


#:import Factory kivy.factory.Factory

<PopupStart@Popup>:
    id : popup_start
    title: \"Start Function Pop-up\"
    auto_dismiss: False
    size_hint : (.4, .4)

    RelativeLayout:
        size_hint : (.8, .9)
        Button:
            text: \'Close me!\'
            size_hint : (.45, .25)
            pos_hint : {\'center_x\':0.5, \'y\':0.1}
            on_release: root.dismiss()
        Label:
            text : \"The start function will run the AI Algorithm \\n and will be 
            provided soon\"
            font_size : 15
            size_hint : (.55, .45)
            pos_hint : {\'center_x\':0.5, \'top\':1}

<PopupCalibrate@Popup>:
    id : popup_calibrate
    title: \"Calibrate Function Pop-up\"
    auto_dismiss: False
    size_hint : (.4, .4)

    RelativeLayout:
        size_hint : (.8, .9)
        Button:
            text: \'Close me!\'
            size_hint : (.45, .25)
            pos_hint : {\'center_x\':0.5, \'y\':0.1}
            on_release: root.dismiss()
        Label:
            text : \"The calibrate function will run the Camera Calibration \\n and 
                    will be provided soon\"
            font_size : 13
            size_hint : (.55, .45)
            pos_hint : {\'center_x\':0.5, \'top\':1}


<CameraView>:
    playing_camera : playing_camera     #to reference in Python Code
    Camera:
        id : playing_camera
        play : True
        index : 0

    Label:
        text : \"Camera n.%s\" % str(playing_camera.index)
        font_size : \"15sp\"
        size_hint : (.3,.1)
        pos_hint : {\'center_x\':0.5, \'top\':1}
        bold : True


<ControlsView>:

    focus_value : focus_slider.value

    Button:
        id : btn_start
        text : \"Start\"
        font_size : 20
        size_hint : (0.7,.1)
        pos_hint :  {\'center_x\':0.5, \'y\':0.05}
        background_normal : \"\"
        background_color : (0,1,0,.5)
        bold : True
        on_release: Factory.PopupStart().open()
        #Check where the function definition should be placed
                                                       

    Button:
        id : btn_calibrate
        text : \"Calibrate\"
        font_size : 18
        size_hint : (0.7,.1)
        pos_hint  :  {\'center_x\':0.5, \'top\':0.75}
        background_normal : \"\"
        background_color : (0, 0, 1, .5)
        on_release: Factory.PopupCalibrate().open()


    Label:
        text : \"logic.portable\"
        font_size : 25
        pos_hint : {\'top\':1.45}

    Label:
        text : \"Gewicht in g\"
        pos_hint : {\'center_x\':0.5, \'top\':1.35}
        color : (1,0,0,.5)

    Label:
        text : \"Focus\"
        font_size : 15
        pos_hint : {\'center_x\': .5, \'center_y\': .27}


    Slider:
        id : focus_slider
        value_track : True
        value_track_color : [1, 0, 0, 1]
        range : (20, 100)                                  
        value : 20
        step : 1
        pos_hint : {\'center_x\': .5, \'center_y\': .25}
        size_hint_y : None
        height : 50
        on_value : root.focus_value = self.value


    Label:
        text : \"Focus at %scm\" % str(root.focus_value)
        font_size : 10
        pos_hint : {\'center_x\': .5, \'center_y\': .22}


<DropDownButton@Button>:
    size_hint_x: .7
    size_hint_y: None
    height: 25


<CameraDropDown>:

    DropDownButton:
        text: \'Camera 1\'
        on_release: root.select(self.text)

    DropDownButton:
        text: \'Camera 2\'
        on_release: root.select(self.text)

    DropDownButton:
        text: \'Camera 3\'
        on_release: root.select(self.text)

    DropDownButton:
        text: \'Camera 4\'
        on_release: root.select(self.text)
   
<InteractiveGUI>:

    CameraView:
        id : cameraview
        size_hint_x : 4

    ControlsView:

我的猜测是 mainbutton 的定义应该放在 ControlsView 类的__init__() Method 中。

我想了解为什么它不能像我使用它的方式那样工作,以及是否有人可以澄清 kivy 类和 App 的工作方式。

更具体地说,我想了解以下内容:

  • 应用程序的build() 方法中应该写什么。

  • 什么应该放在自定义类的__init__() 方法中。

  • 什么可以放在自定义类的__init__() 方法之外。

  • 使用 kivy 时将代码放在类定义之外是否重要?目的是什么? (参考我在类定义之外放置“mainbutton”的示例)

  • 在 kv 语言中,通过&lt;CustomClass&gt; 定义规则与覆盖类的__init()__ 方法相同吗?

  • 在 kv 语言中使用缩进与在类的 __init()__ 方法中使用 self.add_widget() 相同吗?

如果你们中的任何人可以帮助我澄清这些问题或参考涵盖此示例的良好来源,我将非常感激。

  • 除非您在方法 build 中执行类似 ControlsView.add_widget(mainbutton) 的操作,否则您的错误消息与您的代码不匹配。

标签: python kivy


【解决方案1】:

代码行:

ControlsView().add_widget(mainbutton)

正在创建ControlsView 的新实例,然后在ControlsView 的该实例上调用add_widget(),然后丢弃ControlsView 的该新实例。如果您希望 mainbutton 出现在您的 GUI 中,您必须将该小部件添加到您的 GUI 中的 ControlsView

首先,删除有问题的行:

ControlsView().add_widget(mainbutton)

并添加一些代码以实际将mainbutton 添加到ControlsView 的正确实例中:

class ControlsView(RelativeLayout):
    def on_kv_post(self, base_widget):  # runs after the kv rules for this class have been run
        self.add_widget(mainbutton)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-20
    • 1970-01-01
    • 2021-06-19
    • 2013-10-28
    • 2018-08-19
    • 1970-01-01
    • 2020-09-01
    相关资源
    最近更新 更多