python - 通过名称从其父级访问 Gtk3 小部件

标签 python parent-child gtk3

我的程序从配置文件中读取。它根据配置文件在窗口上加载 Gtk3 小部件。

示例配置文件:

[Clock1]
format = %H:%M:%S
color = #FF0000

[Clock2]
format = %H:%M
bgColor = #00FF00

因此,我已经创建了一个自己的类,例如时钟类型小部件,我称之为时钟。

例子:

#!/usr/bin/env python

from gi.repository import Gtk, Gdk

import output, Defaults.widget
from time import gmtime, strftime

receiver="Clock"

class Widget():
    def __init__(self, parentName, name):
        print "ADDING CLOCK"
        self.gtkwidget=Gtk.Label();
        self.format= Defaults.widget.defaultClockFormat
        self.name=name+parentName
        self.gtkwidget.set_name(self.name)

    def update(self):
        print "Setting clock text to", strftime(self.format, gmtime())
        self.gtkwidget.set_text(strftime(self.format, gmtime()))

    def runCommand(self, command, lineCount, configurationFile):
        #GMTTIME TRUE OR FALSE
        print "I am about to run", command, "from inside the Clock widget!"

        if(command.startswith("format=")):
            parts=command.split("=")
            if(len(parts)!=2):
                output.stderr(configurationFile+", line "+str(lineCount)+": Badly formatted command 'format': Format: format = format.\nSkipping...")
                return
            
            self.format=parts[1]

    def widget(self):
        return self.gtkwidget

解释:

  1. 代码读取配置文件并发现它必须创建一个时钟小部件。所以它创建了一个 Clock 类,其中有一个 GtkLabel 作为变量。 runCommand 函数将配置文件读取的任何更多属性应用于小部件。例如。时钟的 format 属性。

  2. update 函数从 WidgetManager 类中每 1 秒运行一次,以保持时间更新。

  3. widget() 函数,一旦没有要添加的小部件的命令(属性),就会运行以返回 GtkWidget 并将其添加到主窗口.

上面的代码可以正常运行一段时间,但随后标签会在很短的随机时间内(1-2 分钟或更短)停止更新。

enter image description here

代码成功运行到 18:53:31,然后标签停止更新。我猜 Gtk 在内部将对象移动到另一个内存,我不能再用我的旧对象访问它(?)。

我该如何解决这个问题?我应该做些不同的事情吗?

我想将父部件(Gtk.Window 子类)传递给子部件(Clock)并按名称搜索 Gtk.Label 表示 self.gtkwidget(通过遍历子项?)。因此,通过名称获取 Gtk.Widget,将其转换为 Gtk.Label 并调用更新代码。我该如何实现?

另一方面,我认为我想多了,也许有更简单的解决方案。

编辑

经过一些测试,我决定将 parent 作为参数传递给子(widget)的构造函数,并在子的 update() 函数上传递给运行父函数并从那里检查字符串(直接从父窗口访问子 GtkWidgets)。请注意,此时,父级的唯一子级是一个标签(GtkLabel)。 有一些有趣的结果

代码如下:

#UPDATE FUNCTION OF THE CHILD
def update(self):
        print "Setting clock text to", strftime(self.format, gmtime())
        self.parent.runFromChildToParent(self.gtkwidget, strftime(self.format, gmtime()))
        self.gtkwidget.set_text(strftime(self.format, gmtime()))

#PARENT FUNCTION CALLED FROM THE CHILD
def runFromChildToParent(self, child, textToSet):
    for childd in self.get_children():
        print "The current text on the child is", childd.get_text()
        childd.set_text(textToSet)
        print childd, child

结果:

enter image description here

一些注意事项:

  1. 小部件在子窗口和父窗口的子窗口上的内存地址是相同的,即使在标签的文本停止更新之后也是如此。即使这样,两个对象都引用相同的内存地址。

  2. 如果您注意到,我直接从窗口的子窗口(名为 childd)调用 set_text 函数,这也不会更新值.

这不是我代码中的错误并且我应该强制重绘 Gtk 的可能性有多大?

编辑2

即使在 set_text 之后使用 self.gtkwidget.queue_draw(),问题似乎仍然存在。

最佳答案

您必须使用 GObject timeout_add 函数来定期更新 ui...

请不要那么懒惰,下次阅读文档!你可以写出几千行完美的代码,但你是否厌倦了在谷歌上搜索“Gtk update UI periodically”?为什么?

关于python - 通过名称从其父级访问 Gtk3 小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26107124/

相关文章:

ios - 在 CoreData 中修改子项的父属性值

c - 如何查找 GtkLabel 当前的字体

python - 为什么基于 iLocation 的 bool 索引不起作用?

python - python中每组与sqlite3最接近的匹配?

ruby-on-rails - 从父表单创建一定数量的子对象

html - 将样式应用于具有特定值的孙子的祖 parent

perl - 在备用 X11 显示器上打开弹出菜单时 Gtk3 崩溃

linux - gtk3 动画进度条不可能?

python - 如何使用 tkinter 测量在 python 中按下按钮之间耗时?

python - 如何加快第一列分割文件的代码