kil*_*bee 6 python widget kivy
我是Kivy的新手,我有这个小的演示片段来演示我的问题:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
class KivyGuiApp(App):
def build(self):
return root_widget
class MyBox(BoxLayout):
def print_ids(self, *args):
print("\nids:")
for widget in self.walk():
print("{} -> {}".format(widget, widget.id))
def print_names(self, *args):
print("\nnames:")
for widget in self.walk():
print("{} -> {}".format(widget, widget.name))
root_widget = Builder.load_string("""
MyBox:
id: screen_manager
name: 'screen_manager'
SimpleLayout:
id: simple_layout
name: 'simple_layout'
<SimpleLayout@BoxLayout>:
id: simple_layout_rule
name: 'simple_layout_rule'
Button:
id: button_ids
name: 'button_ids'
text: 'print ids to console'
on_release: app.root.print_ids()
Button:
id: button_names
name: 'button_names'
text: 'print names to console'
on_release: app.root.print_names()
""")
if __name__ == '__main__':
KivyGuiApp().run()
Run Code Online (Sandbox Code Playgroud)
因此,当您运行代码时,将有两个按钮:
我的问题是:
奖金问题:
编辑:
所以这是我能想到通过独特的"全局"id引用小部件的最简单方法.
首先,我创建了一个将由我的App类继承的类:
class KivyWidgetInterface():
''' interface for global widget access '''
global_widgets = {}
def register_widget(self, widget_object):
''' registers widget only if it has unique gid '''
if widget_object.gid not in self.global_widgets:
self.global_widgets[widget_object.gid] = widget_object
def get_widget(self, widget_gid):
''' returns widget if it is registered '''
if widget_gid in self.global_widgets:
return self.global_widgets[widget_gid]
else:
return None
Run Code Online (Sandbox Code Playgroud)
因此,仅当窗口小部件具有gid(窗口小部件类变量)时才会注册它,并且它是唯一的.这样我就可以在这个dict中只存储重要的小部件.此外,它可以从.kv和python端轻松访问.
现在我创建gid变量并将它们注册到.kv中的dict:
<PickDirectory>:
gid: 'pick_directory'
on_pos: app.register_widget(self)
on_selection: app.get_widget('filelist').some_func()
<FileListView>:
gid: 'filelist'
on_pos: app.register_widget(self)
Button:
name: 'not important'
Button:
gid: 'tab_browse_button1'
on_pos: app.register_widget(self)
Run Code Online (Sandbox Code Playgroud)
实际上困扰我的是我在这个"全局"字典中使用'on_pos'事件注册我的小部件...我真的不喜欢,但我无法找到任何可靠的方法来调用寄存器方法之后widget被初始化了(on_pos在init阶段之后被调用,当widget被定位,之后非常罕见,所以...似乎是最不用的方式,用我对kivy api的知识来做这个,命令小部件用.kv初始化语言等;所以如果有更好的方法,我会对任何指针非常粗糙).
无论如何,这样我就可以轻松地将任何事件绑定到任何类中的任何方法,直接来自.kv
要记住的一件事是gid(全局id)需要在全球范围内是独一无二的,但我没有发现比在本地保持id唯一更令人不安(这对我来说可能同样甚至更令人困惑).正如我所说的 - 我想以不同的方式注册小部件,但我找不到任何其他可靠的方法(并且我没有发现Clock对于这些事情是可靠的).
实际上,没有。根据文档,name在您的小部件中是一个变量,id只是一个小部件参考weakref。也许python 文档会帮助你理解它是如何工作的。您所做的是打印id,而不是小部件内的变量“id”。
在kivy docs 中解释说,在kv解析之后,id 被收集到一个 ObservableDict 中。id 的工作方式类似于 python dict 键,id:Widget但前提是通过字典(ids)访问。我认为kv解析器只是将所有 id 放入 dict 并且仅适用于它创建的 dict。
Button:
id: test
text: 'self.id'
#or
Button:
id: 'test'
text: 'self.id'
Run Code Online (Sandbox Code Playgroud)
即使它像字符串一样编写,也没有任何变化。所以我希望解析器的行为是这样的:抓取后面的任何整个单词id:,变成一个字符串,附加到ids字典中<id_string>:Widget_weakref,id在你的字典中忘记.kv或者如果它.kv再次使用则忽略它。因此,当直接调用 id 时(不是类似字典的 d[key]),它的行为就像一个空/None变量。我希望我是对的。
回答第二个和第三个:
例如,如果您的意思是直接通过idin访问小部件,那么是的。MyBoxSimpleLayout
蟒蛇类:
self.ids.simple_layout
Run Code Online (Sandbox Code Playgroud)
kv MyBox 规则:
MyBox:
id: screen_manager
name: 'screen_manager'
BoxLayout:
Label:
id: my_label
text: 'test'
Button:
text: 'button'
on_release: self.text = root.ids.my_label.text
Run Code Online (Sandbox Code Playgroud)
但是,要像 python 全局变量那样通过 id 访问所有小部件,这是不可能的。您需要先访问类/小部件,然后再访问它的ids字典
| 归档时间: |
|
| 查看次数: |
11452 次 |
| 最近记录: |