Kivy实例的Button小部件添加到GridLayout创建时缺少pos值?

时间:2016-02-20 07:49:32

标签: python button widget kivy

在下面的python / kivy代码中,我尝试创建一个名为MainWindow的新GridLayout实例(具有附加功能的main),并使用Button小部件填充它将其返回MainApp.build()

我已添加Debug按钮,以便在按下按钮时打印pos所有子女的main值。

其他Btn按钮会在按下时打印self.pos

build()方法中,我会在返回main之前打印main中所有孩子的位置。它确实显示了孩子的完整列表,但为所有孩子的pos值提供了[0,0]。

但是,on_release()按钮的Btn方法在调用时会给出正确的self.pos值。

有没有办法在初始化时为pos的子项获取正确的main值,而无需调用Btn类中的方法?

我怀疑这与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()

1 个答案:

答案 0 :(得分:1)

在将这些按钮放在窗口上之前,您试图读取按钮的位置。它们放在build函数返回后。要尽快读取这些位置,您需要一个单独的功能,该功能将在短暂延迟后执行。使用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))