Accessing a Gtk3 widget from a parent by name
My program is reading from a config file. It loads gtk3 widgets in a window based on a config file.
Sample config file:
[Clock1] format = %H:%M:%S color = #FF0000 [Clock2] format = %H:%M bgColor = #00FF00
So I made my own class for example. A clock widget, and I named it Clock.
#!/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 def widget(self): return self.gtkwidget
The code reads the configuration file and sees that it needs to create a Clock widget. Thus, it creates a Clock class with a variable inside the GtkLabel. The function will
apply more properties read by the config file to widgets. For example. property
for the clock.
runs every 1 second from the class
to keep the time updated.
, after there are no more commands (properties) for the added widget, is run to return the GtkWidget and add it to the main window.
The above code works very well for some time, but then the label stops updating for some short random time (1-2 minutes or less).
The code runs until 18:53:31, after which the shortcut stops updating. My guess is that Gtk internally moves the object to a different memory and I can no longer access it with my old object (?).
How can I solve this problem? Should I be doing something differently?
I was thinking about passing a parent widget (which is a subclass
) to the child (
) and searching by name
(by iterating through the children?). So, get
by its name, cast it before,
and call the update code for it. How to implement this?
On the other hand, I think I am overdoing it and there is perhaps a simpler solution available.
After some tests, I decided to pass
as an argument to the child constructor and the
child function to run the parent function and check the string there (directly accessing the GtkWidgets children from the parent window). Note that at this point, the only parent of the parent is the label (GtkLabel). There were interesting results .
The code looks like this:
#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
The widget memory addresses for the child and child of the parent window are the same even after the label text stops updating. Even then, both objects refer to the same memory address.
If you noticed, I am calling the function
directly from the child (named
) of the window and that also does not update the value.
What is the likelihood that this is not a bug in my code and should I force Gtk to redraw?
problem seems to persist.
source to share