我的程序从配置文件中读取。它根据配置文件在窗口上加载 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
解释:
代码读取配置文件并发现它必须创建一个时钟小部件。所以它创建了一个 Clock 类,其中有一个 GtkLabel 作为变量。
runCommand
函数将配置文件读取的任何更多属性应用于小部件。例如。时钟的format
属性。update
函数从WidgetManager
类中每 1 秒运行一次,以保持时间更新。widget()
函数,一旦没有要添加的小部件的命令(属性),就会运行以返回 GtkWidget 并将其添加到主窗口.
上面的代码可以正常运行一段时间,但随后标签会在很短的随机时间内(1-2 分钟或更短)停止更新。
代码成功运行到 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
结果:
一些注意事项:
小部件在子窗口和父窗口的子窗口上的内存地址是相同的,即使在标签的文本停止更新之后也是如此。即使这样,两个对象都引用相同的内存地址。
如果您注意到,我直接从窗口的子窗口(名为
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/