Kivy - 通过引用根属性动态添加按钮
Kivy - Add buttons dynamically with referring to root atributes
所以我尝试分解我的问题:
我有两个屏幕,当我从一个屏幕切换到另一个屏幕时,它应该会在第二个屏幕上动态生成按钮(id:“thema_screen”)。这些按钮在第二个屏幕上创建为 GridLayout,其 ID 为:“grid_thema_screen”
现在,如果我更改 window 大小,我希望按钮的 font_size 自动更改,这与 kivy 中的 font_size: min(root.height, root.width) / 10
配合得很好-file,但是当我在 python-file add_widget(Button(text = str(i+2), font_size = min(self.root.height, self.root.width) / 2))
中写入时,它不起作用
它改变了一次字体大小,但如果我重新设置 window,字体就不再改变了。这是我的 python 文件的代码片段:
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 中动态创建按钮,为什么字体大小不再自动更改,那就太好了。
非常感谢。
所以当您以编程方式添加按钮时字体大小没有改变的原因是因为 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 文件中创建一个按钮,其 font_size
属性由您在该实例中传递的值定义。
您可以做几件事,您可以在 Wurzel
class 中创建 NumericProperty
并将按钮绑定到此 属性(请参阅 https://kivy.org/doc/stable/api-kivy.properties.html for more details). However, since your having the issues with resizing, I think the easiest thing to do is take advantage of the on_size
call back (see https://kivy.org/doc/stable/api-kivy.event.html了解更多详情)。
Wurzel
class 应该是这样的:
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 的解决方案(非常感谢你!!!)。我把@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"
所以我尝试分解我的问题:
我有两个屏幕,当我从一个屏幕切换到另一个屏幕时,它应该会在第二个屏幕上动态生成按钮(id:“thema_screen”)。这些按钮在第二个屏幕上创建为 GridLayout,其 ID 为:“grid_thema_screen”
现在,如果我更改 window 大小,我希望按钮的 font_size 自动更改,这与 kivy 中的 font_size: min(root.height, root.width) / 10
配合得很好-file,但是当我在 python-file add_widget(Button(text = str(i+2), font_size = min(self.root.height, self.root.width) / 2))
它改变了一次字体大小,但如果我重新设置 window,字体就不再改变了。这是我的 python 文件的代码片段:
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 中动态创建按钮,为什么字体大小不再自动更改,那就太好了。 非常感谢。
所以当您以编程方式添加按钮时字体大小没有改变的原因是因为 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 文件中创建一个按钮,其 font_size
属性由您在该实例中传递的值定义。
您可以做几件事,您可以在 Wurzel
class 中创建 NumericProperty
并将按钮绑定到此 属性(请参阅 https://kivy.org/doc/stable/api-kivy.properties.html for more details). However, since your having the issues with resizing, I think the easiest thing to do is take advantage of the on_size
call back (see https://kivy.org/doc/stable/api-kivy.event.html了解更多详情)。
Wurzel
class 应该是这样的:
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 的解决方案(非常感谢你!!!)。我把@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"