Kivy - 通过引用根属性动态添加按钮
Posted
技术标签:
【中文标题】Kivy - 通过引用根属性动态添加按钮【英文标题】:Kivy - Add buttons dynamically with referring to root atributes 【发布时间】:2021-06-27 17:34:46 【问题描述】:所以我尝试解决我的问题:
我有两个屏幕,当我从一个屏幕切换到另一个屏幕时,它应该在第二个屏幕上动态生成按钮(id:“thema_screen”)。这些按钮在第二个屏幕上创建为 GridLayout,其 id 为:“grid_thema_screen”
现在,如果我更改窗口大小,我希望按钮的 font_size 自动更改,这与 kivy-file 中的font_size: min(root.height, root.width) / 10
效果很好,但是当我将其写入 python 文件 add_widget(Button(text = str(i+2), font_size = min(self.root.height, self.root.width) / 2))
它改变了一次字体大小,但是如果我重新调整窗口,字体就不再改变了。这是我的python文件的代码sn-p:
class Wurzel(MDBoxLayout):
def __init__(self, **kwargs):
super(Wurzel, self).__init__(**kwargs)
def changeScreen(self, next_screen):
if next_screen == "thema_screen":
self.ids.wurzel_screen_manager.current = next_screen
for i in range(12):
self.ids.thema_screen.ids.grid_thema_screen.add_widget(Button(text = str(i+2), font_size = min(self.root.height,
self.root.width) / 10))
这里是我的 kivy 文件:
<Wurzel>:
orientation: 'vertical'
spacing: 20
MDToolbar:
title: 'Hellllooo'
left_action_items: [["menu", lambda x: app.navigation_klick()], ["apple", lambda x: app.navigation_klick()]]
elevation: 8
ScreenManager:
id: wurzel_screen_manager
StartScreen:
name: "start_screen"
ThemaScreen:
id: thema_screen
name: "thema_screen"
<StartScreen@MDScreen>:
BoxLayout:
orientation: "vertical"
...
<ThemaScreen@MDScreen>:
GridLayout:
id: grid_thema_screen
cols: 3
padding: root.width * .01, root.height * .01
spacing: min(root.width, root.height) * .02
Button:
text: "1"
font_size: min(root.height, root.width) / 10
size_hint: None, None
size: self.font_size*3, self.font_size*3
所以,如果有人可以帮助我并告诉我,如果我在 Python 中动态创建按钮,为什么字体大小不再自动更改,那就太好了。 非常感谢。
【问题讨论】:
【参考方案1】:所以当您以编程方式添加按钮时字体大小不会改变的原因是因为font_size
属性没有绑定到任何东西。当您在 kv 文件中创建一个小部件时,解释器会自动将您的属性相互绑定。这意味着当您输入时:
font_size: min(root.height, root.width) / 10
在 kv 文件中,当 root.height
更新时,font_size
也会更新。但是,写
Button(font_size = min(self.root.height, self.root.width) / 2)
在您的 Python 文件中创建一个 Button,其 font_size
属性由您在该实例中传递的值定义。
您可以做几件事,您可以在您的 Wurzel
类中创建 NumericProperty
并将您的 Buttons 绑定到此属性(有关详细信息,请参阅 https://kivy.org/doc/stable/api-kivy.properties.html)。但是,由于您在调整大小时遇到问题,我认为最简单的方法是利用 on_size
回调(有关更多详细信息,请参阅 https://kivy.org/doc/stable/api-kivy.event.html)。
Wurzel
类应该是这样的:
class Wurzel(MDBoxLayout):
def __init__(self, **kwargs):
super(Wurzel, self).__init__(**kwargs)
def changeScreen(self, next_screen):
if next_screen == "thema_screen":
self.ids.wurzel_screen_manager.current = next_screen
for i in range(12):
self.ids.thema_screen.ids.grid_thema_screen.add_widget(Button(text = str(i+2), font_size = min(self.root.height, self.root.width) / 10))
def update_font_size(self, *args):
for button in self.children: # Loop through all children
if isinstance(button, Button): # Check if child is a button (may not need)
button.font_size = min(self.root.height, self.root.width) / 10)) # Update font_size
on_size = update_font_size # Set a callback for on_size
【讨论】:
您好 jda5,非常感谢您的回答。我理解并尝试了您的代码,但我不确定将on_size = update_font_size # Set a callback for on_size
部分放在哪里。我试图在 on_size: self.update_font_size()
:但它显示“声明后数据无效”。你能告诉我,在哪里写?所以我找到了 jda5 的解决方案(非常感谢你!!!)。我稍微改了一下@jda5的方法:
def update_font_size(self, *args):
for button in self.ids.thema_screen.ids.grid_thema_screen.children: # Loop through all children
if isinstance(button, Button): # Check if child is a button (may not need)
button.font_size = min(self.height, self.width) / 20 # Update font_size
然后我将“on_size”回调放到 kivy 文件中:
ScreenManager:
id: wurzel_screen_manager
StartScreen:
name: "start_screen"
ThemaScreen:
on_size: app.root.update_font_size()
id: thema_screen
name: "thema_screen"
【讨论】:
以上是关于Kivy - 通过引用根属性动态添加按钮的主要内容,如果未能解决你的问题,请参考以下文章
如何将纯 python 中动态创建的按钮添加到用 Kivy 语言编写的 kivy 布局中?
如何根据 Widget Kivy 属性更新**动态添加的**椭圆(不使用 Builder)的颜色?