添加到 GridLayout 的 Button 小部件的 Kivy 实例在创建时缺少 pos 值?
Kivy Instance of Button widget added to GridLayout missing pos value on creation?
在我下面的 python/kivy 代码中,我尝试创建一个名为 main
的 MainWindow
的新实例(这是一个具有附加功能的 GridLayout
),填充它带有 Button 小部件和 return 它在 MainApp.build()
.
我添加了一个 Debug
按钮,当按下按钮时打印 main
的所有 children 的 pos
值。
其他 Btn
按钮在按下时将打印 self.pos
。
在 build()
方法中,我在 returning main
之前打印 main
中所有 children 的位置。它确实显示了 children 的完整列表,但为所有 children 的 pos
值给出了 [0,0]。
但是,Btn
按钮的 on_release()
方法在调用时会给出正确的 self.pos
值。
有没有办法在初始化时为 main
的 children 获取正确的 pos
值,而不必调用 Btn
[=54] 中的方法=]?
我怀疑这与 GridLayout
处理 Widget 定位的方式有关。
我已将 main
全局化以用于我正在处理的这个项目中的一些其他功能。我希望除了整个“你不应该使用全球价值观”之外,这不是一个大问题。
from kivy.app import App
from kivy.graphics import *
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
class MainWindow(GridLayout): # main class
def popbtns(self):
i = 1
while (i <= 29):
self.add_widget(Btn(text='Btn #' + str(i) + ' at '+ str(self.pos)))
i = i + 1
class Btn(Button): # button class
def on_release(self):
print('self.pos= ' + str(self.pos))
class Debug(Button): # debug button
def on_release(self):
for child in self.parent.children:
print(str(child) + ' pos is ' + str(child.pos))
class MainApp(App):
def build(self):
global main
main = MainWindow(cols=7)
# make background
with main.canvas:
Rectangle(pos=main.pos, size=Window.size)
# populate gridlayout with Buttons
main.add_widget(Debug(text='debug',background_color=(1,0,0,1)))
main.popbtns()
# print position of buttons...
for child in main.children:
print(str(child) + ' pos is ' + str(child.pos))
return main
if __name__ == "__main__":
MainApp().run()
您试图在这些按钮放置在 window 上之前读取按钮的位置。它们位于 build
函数 returns 之后。要尽快读取这些位置,您需要一个单独的函数,该函数将在短暂的延迟后执行。使用 Clock 实现:
from kivy.clock import Clock
...
class MainApp(App):
def build(self):
main = MainWindow(cols=7)
self.root = main # don't use global!
# make background
with main.canvas:
Rectangle(pos=main.pos, size=Window.size)
# populate gridlayout with Buttons
main.add_widget(Debug(text='debug', background_color=(1, 0, 0, 1)))
main.popbtns()
# print position of buttons...
Clock.schedule_once(self.delayed_function, 0.1)
def delayed_function(self, dt):
self.print_buttons_pos()
def print_buttons_pos(self):
for child in self.root.children:
print(str(child) + ' pos is ' + str(child.pos))
在我下面的 python/kivy 代码中,我尝试创建一个名为 main
的 MainWindow
的新实例(这是一个具有附加功能的 GridLayout
),填充它带有 Button 小部件和 return 它在 MainApp.build()
.
我添加了一个 Debug
按钮,当按下按钮时打印 main
的所有 children 的 pos
值。
其他 Btn
按钮在按下时将打印 self.pos
。
在 build()
方法中,我在 returning main
之前打印 main
中所有 children 的位置。它确实显示了 children 的完整列表,但为所有 children 的 pos
值给出了 [0,0]。
但是,Btn
按钮的 on_release()
方法在调用时会给出正确的 self.pos
值。
有没有办法在初始化时为 main
的 children 获取正确的 pos
值,而不必调用 Btn
[=54] 中的方法=]?
我怀疑这与 GridLayout
处理 Widget 定位的方式有关。
我已将 main
全局化以用于我正在处理的这个项目中的一些其他功能。我希望除了整个“你不应该使用全球价值观”之外,这不是一个大问题。
from kivy.app import App
from kivy.graphics import *
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
class MainWindow(GridLayout): # main class
def popbtns(self):
i = 1
while (i <= 29):
self.add_widget(Btn(text='Btn #' + str(i) + ' at '+ str(self.pos)))
i = i + 1
class Btn(Button): # button class
def on_release(self):
print('self.pos= ' + str(self.pos))
class Debug(Button): # debug button
def on_release(self):
for child in self.parent.children:
print(str(child) + ' pos is ' + str(child.pos))
class MainApp(App):
def build(self):
global main
main = MainWindow(cols=7)
# make background
with main.canvas:
Rectangle(pos=main.pos, size=Window.size)
# populate gridlayout with Buttons
main.add_widget(Debug(text='debug',background_color=(1,0,0,1)))
main.popbtns()
# print position of buttons...
for child in main.children:
print(str(child) + ' pos is ' + str(child.pos))
return main
if __name__ == "__main__":
MainApp().run()
您试图在这些按钮放置在 window 上之前读取按钮的位置。它们位于 build
函数 returns 之后。要尽快读取这些位置,您需要一个单独的函数,该函数将在短暂的延迟后执行。使用 Clock 实现:
from kivy.clock import Clock
...
class MainApp(App):
def build(self):
main = MainWindow(cols=7)
self.root = main # don't use global!
# make background
with main.canvas:
Rectangle(pos=main.pos, size=Window.size)
# populate gridlayout with Buttons
main.add_widget(Debug(text='debug', background_color=(1, 0, 0, 1)))
main.popbtns()
# print position of buttons...
Clock.schedule_once(self.delayed_function, 0.1)
def delayed_function(self, dt):
self.print_buttons_pos()
def print_buttons_pos(self):
for child in self.root.children:
print(str(child) + ' pos is ' + str(child.pos))