从其父级按名称访问Gtk3小部件

时间:2014-09-29 19:11:30

标签: 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小部件。所以它使一个Clock类在其中有一个GtkLabel作为变量。 runCommand函数适用于窗口小部件,配置文件读取的任何其他属性。例如。时钟的format属性。

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

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

  4. 上面的代码运行得很好一段时间,但随后标签在一些短暂的随机时间(1-2分钟或更短)内停止更新。

    enter image description here

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

    我该如何解决这个问题?我应该采取不同的做法吗?

    我想过将父窗口小部件(Gtk.Window子类)传递给子(Clock)并按名称搜索代表Gtk.Label的{​​{1}}(通过迭代孩子?)。因此,请按名称获取self.gtkwidget,将其投放到Gtk.Widget并调用更新代码。我该如何实现呢?

    另一方面,我认为我正在思考它,也许还有一个更简单的解决方案。

    修改

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

    代码如下:

    update()

    结果:

    enter image description here

    有些事情需要注意:

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

    2. 如果您注意到,我直接从窗口的子项(名为#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 )调用set_text函数,并且这也不会更新该值。

    3. 这不是我代码中的错误的可能性,我应该强制进行Gtk重绘吗?

      EDIT2

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

1 个答案:

答案 0 :(得分:2)

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

请不要这么懒,下次再阅读文档!您可以编写数千条完美的代码行,但您又无法在Google中搜索“Gtk update UI”吗?为什么呢?