【问题标题】:Kivy Instance of Button widget added to GridLayout missing pos value on creation?添加到 GridLayout 的 Button 小部件的 Kivy 实例在创建时缺少 pos 值?
【发布时间】:2016-02-20 07:49:31
【问题描述】:

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

我添加了一个Debug 按钮,用于在按下按钮时打印main 的所有子级的pos 值。

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

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

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

有没有办法在初始化时为main 的子代获取正确的pos 值,而无需调用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()

【问题讨论】:

    标签: python button widget kivy


    【解决方案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))
    

    【讨论】:

    • 谢谢,这很有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-23
    • 1970-01-01
    相关资源
    最近更新 更多