gpt4 book ai didi

python - 使用 id 访问动态添加的小部件

转载 作者:行者123 更新时间:2023-12-04 14:19:24 25 4
gpt4 key购买 nike

目标
我想创建一个小脚本来动态添加按钮,但仍然允许我通过 root 对特定按钮执行功能。


我的方法
我做了这个脚本。

它能够在顶部动态添加大按钮。
每个按钮在按下时都会稍微改变自己的颜色。

它的底部有两个小按钮。
第一个按钮在顶部动态添加新的大按钮。
第二个按钮重置顶部第一个大按钮的颜色。

我的代码

#!/usr/bin/env python3
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout

Builder.load_string('''
<RootWidget>:
Button:
text: 'Add'
size_hint: (None, None)
size: (40, 40)
pos: (40, 40)
group: 'action'
on_press: root.createNextTarget()
Button:
text: 'res'
size_hint: (None, None)
size: (40, 40)
pos: (100, 40)
group: 'action'
on_press: root.resetTarget()
''')

class RootWidget(FloatLayout):
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
#note: self.ids isn't populated yet. I guess we can't use it yet.
self.createNextTarget()

def resetTarget(self):
f_target = self.ids['targetbutton0']
f_target.background_color = (1.0, 1.0, 1.0, 1.0)
return True

def countTargets(self):
return [str(x.__class__.__name__) for x in self.children if x != None].count('TargetButton')

def createNextTarget(self):
f_nextButton = TargetButton(id="targetbutton"+str(self.countTargets()),
size_hint=(None, None),
pos=(80 + (10 + 60) * self.countTargets(), 100),
size=(60, 60),
background_normal = '',
background_color = (1, 1, 1, 1),
group = 'target')
self.add_widget(f_nextButton)
f_nextButton.bind(on_press=TargetButton.lowerAllRGB)

class TargetButton(Button):
def __init__(self, **kwargs):
super(TargetButton, self).__init__(**kwargs)

def lowerAllRGB(self):
f_r, f_g, f_b, f_a = self.background_color
if f_r >= 0.1: f_r = f_r - 0.1
if f_g >= 0.1: f_g = f_g - 0.1
if f_b >= 0.1: f_b = f_b - 0.1
self.background_color = (f_r, f_g, f_b, f_a)
return True

class TestApp(App):
def build(self):
return RootWidget()

def on_stop(self):
print("TestApp.on_stop: finishing", self.root.ids)

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

问题
如果我尝试点击重置按钮(通过 root.ids 访问小部件),我会收到错误消息:KeyError: 'targetbutton0'

找到a post about a similar problem后,我认为 root.idsRootWidget.__init__ 期间不会工作。
但是当我在 RootWidget.__init__ 完成后使用按钮添加按钮时,TestApp.on_stop() 仍然打印: TestApp.on_stop:完成{}

因此 root.ids 仍然是空的,并且似乎不包含任何动态添加的小部件,尽管我为每个小部件分配了 id 属性。

我的问题

  1. 考虑到我动态添加小部件的方式,使用 root.ids 是否对我的目的毫无值(value)?
  2. 有没有合适的方法让我通过 id 访问我的小部件?
    我看到了 another question here问类似的东西。但它没有回答我关于动态添加的小部件的问题。

最佳答案

问题 1 - root.ids/self.ids

Given the way I am dynamically adding widgets, is using root.ids just worthless for my purposes?

回答

分配给动态添加的小部件的

id 不存储在 self.idsroot.ids 中。因此,您无法使用 self.ids['targetbutton0']self.ids.targetbutton0 访问动态添加的小部件。如果这样做,您将得到一个 KeyError,因为在 self.ids 中找不到它,这是一个字典类型的属性。

当你的 kv 文件被解析时,Kivy 收集所有标有 id 的小部件并将它们放在这个 self.ids 字典类型属性中.

注意:这些类型的 id(即分配给动态创建的小部件的 id)已弃用,并将在未来的 Kivy 版本中删除。

[WARNING] Deprecated property "<StringProperty name=id>" of object "<kivy.uix.button.Button object at 0x7feeec0968d0>" has been set, it will be removed in a future version

问题2

Is there a decent way for me to access my widgets via id?

解决方案

您可以创建自己的字典类型属性 ID 列表。

片段

from kivy.properties import DictProperty

class RootWidget(FloatLayout):
dynamic_ids = DictProperty({}) # declare class attribute, dynamic_ids

def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
self.createNextTarget()

def resetTarget(self):
f_target = self.dynamic_ids['targetbutton0']
f_target.background_color = (0.0, 1.0, 1.0, 1.0) # cyan colour
return True

...

def createNextTarget(self):
id = "targetbutton" + str(self.countTargets())
f_nextButton = TargetButton(id=id,
size_hint=(None, None),
pos=(80 + (10 + 60) * self.countTargets(), 100),
size=(60, 60),
background_normal = '',
background_color = (1, 1, 1, 1), # white colour
group = 'target')
self.add_widget(f_nextButton)
self.dynamic_ids[id] = f_nextButton
f_nextButton.bind(on_press=TargetButton.lowerAllRGB)

输出

Result

关于python - 使用 id 访问动态添加的小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56587838/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com