Python 中 Kivy 小部件之间的交互

Posted

技术标签:

【中文标题】Python 中 Kivy 小部件之间的交互【英文标题】:Interaction between Kivy widgets in Python 【发布时间】:2016-06-29 20:18:23 【问题描述】:

我正在使用 kivy 做一个项目,但我的复选框有问题。起初我正在尝试编写类似 python 编码的程序(我知道它不干净,但我了解更多)而且我有一个带有这种编码的第一个屏幕:

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.checkbox import CheckBox




class MainScreen(GridLayout):
    def __init__(self,**kwargs):
        e=[]
        super(MainScreen, self).__init__(**kwargs)
        self.cols=2
        def on_checkbox_active(checkbox, value):
            if value:
                e.append(value)
                print e
            else:
                print('The checkbox', checkbox, 'is inactive')

        self.add_widget(Label(text='Inserta assignatures desitjades',font_size=35))
        self.add_widget(Label(text=''))
        ch1 = CheckBox()
        self.add_widget(ch1)
        self.add_widget(Label(text='Termotecnia'))
        ch2 = CheckBox()
        self.add_widget(ch2)
        self.add_widget(Label(text='Termotecnia'))
        ch3 = CheckBox()
        self.add_widget(ch3)
        self.add_widget(Label(text='Termotecnia'))
        ch4 = CheckBox()
        self.add_widget(ch4)
        self.add_widget(Label(text='Termotecnia'))
        b1=Button(text='Exit',background_color=[0.7,0.7,1,1],font_size=24)  
        self.add_widget(b1)
        b2=Button(text='Next',font_size=24,font_color=[1,3,4,0],background_color=[1,2,3,6]) 
        self.add_widget(b2)
        ch1.bind(active=on_checkbox_active)
        ch2.bind(active=on_checkbox_active)
        b1.bind(on_press=exit)
        b2.bind(on_press=reloaded)
...

class SimpleKivy(App):
    def build(self):
        return MainScreen()


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

例如,我想选择两个或三个选项,然后将其保存到下一个屏幕,例如一种选择。如果有人知道如何操作并为下一个屏幕保存信息,那将对我有很大帮助,因为我有所有选项的下一个屏幕的代码,但我想在第一个屏幕中预先选择,然后只使用我已选择。另外,如果有人可以帮助我,我想知道当按下“下一步”按钮时如何过渡到另一个班级(屏幕)。我知道这个问题很简单,但我是 kivy 编程的新手,有些概念非常困难。谢谢。

【问题讨论】:

【参考方案1】:

您想要的是访问其他类中的变量。有时这可能很烦人,你可以用所有__init__() 和其他东西来做这件事,或者......有一种更简单的方法:它是get_running_app()

您可以创建一个字典或其他东西,您可以在其中存储其他类需要访问的任何值。它类似于使用globals 并且它花费更少的代码行数。例如,在您的情况下,您可以使用字典(或嵌套字典、json、...)来存储例如 'checkboxes':'<names of checked ones>',并且在每个初始化中,您可以遍历这些值以制作复选框 active

基本上,您只需要 a = App.get_running_app() 某处以及可以在 main - App - 类中访问的内容。

例子:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
Builder.load_string('''
<Root>:
    MainScreen:
        name: 'main'
    AnotherScreen:
        name: 'another'
<MainScreen>:
    BoxLayout:
        Button:
            text: 'next screen'
            on_release: root.parent.current='another'
        Button:
            text: 'ping!'
            on_release: root.ping()
<AnotherScreen>:
    BoxLayout:
        Button:
            text: 'previous screen'
            on_release: root.parent.current='main'
        Button:
            text: 'ping!'
            on_release: root.ping()
''')

class MainScreen(Screen):
    def __init__(self, **kw):
        super(MainScreen, self).__init__(**kw)
        self.a = App.get_running_app()
    def ping(self):
        print self.a.big_dict['hi']

class AnotherScreen(Screen):
    def ping(self):
        b = App.get_running_app()
        print b.big_dict['hi']

class Root(ScreenManager):
    pass
class SimpleKivy(App):
    big_dict='hi':'hi there!'
    def build(self):
        return Root()
SimpleKivy().run()

你可以看到没有必要调用__init__(),如果你真的不需要,也不需要写更多的代码。

【讨论】:

但是会怎样呢?我有这个想法,但我不知道如何保存信息,因为我必须知道每个复选框的最后状态。如果我有 5 个复选框并且未选中 1 个,我如何将这些信息保存在字典中? 创建一个在每个屏幕变化时运行的函数。要么在某处存储复选框的 ID,要么循环遍历类的每个子项(检查它是否是复选框)并将其状态保存到字典中。您可以按照将小部件添加到类的顺序保存它(假设您有相同数量的复选框),或者这里的选项是 id。例如&lt;chbox's id&gt;:&lt;state&gt; 或嵌套一个'chboxes':&lt;chbox's id&gt;:&lt;state&gt; 好的,谢谢。我已经完成了你所说的一切并且它正在工作。现在我想根据主屏幕的选择创建下一个屏幕,就像一个函数一样。例如,如果我选择第一个复选框和最后一个复选框,则下一个屏幕将为第一个和最后一个输入文本。我如何制作一个程序,它可以根据上一个屏幕的选择自动添加小部件?对不起,如果我问得太多,我对kivy很感兴趣,但我不太了解。谢谢。 好吧,创建 Screen 的基本结构并使用__init__() 从内部构建您的内容。我不确定当你调用add_widget(your_screen) 时是否调用了init,但如果没有,那么你需要在add_widget() 之后手动调用它。在类中,您可以设置一个列表,例如使用 [0,0,0,0] 将其更新为 [1,0,0,1] 从字典中获取值,其中您已经拥有复选框的状态。然后您将遍历列表并为每个 1 添加一个 TextInput 而不是复选框(如果您想创建仅替换两个复选框的相同屏幕)。 好吧,我会打开另一个问题,因为我尝试添加另一个屏幕,但它不能像 GridLayout 那样工作,只能作为屏幕。我可以用 python 语言进行迭代,但我不知道如何用 kivy 语言进行迭代。我将在此处链接我当时的程序代码。非常感谢。

以上是关于Python 中 Kivy 小部件之间的交互的主要内容,如果未能解决你的问题,请参考以下文章

向 Kivy 添加小部件时如何确保功能正常

在 kivy (python) 中更新小部件

用python读/写kivy小部件属性

kivy python 小部件实例或所有小部件

在没有终端的情况下打开 kivy 小部件?

如何在带有python类的kivy中使用下拉小部件