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.

Example:

#!/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

      

Explanation:

  • 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 runCommand

    apply more properties read by the config file to widgets. For example. property format

    for the clock.

  • The function update

    runs every 1 second from the class WidgetManager

    to keep the time updated.

  • The function widget()

    , 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).

enter image description here

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 Gtk.Window

) to the child ( Clock

) and searching by name Gtk.Label

that represents self.gtkwidget

(by iterating through the children?). So, get Gtk.Widget

by its name, cast it before, Gtk.Label

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.

EDIT

After some tests, I decided to pass parent

as an argument to the child constructor and the update()

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

      

Result:

enter image description here

Some notes:

  • 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 set_text

    directly from the child (named childd

    ) 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?

EDIT2

Even after self.gtkwidget.queue_draw()

after, the set_text

problem seems to persist.

+3


source to share


1 answer


You will need to use the timebot function time_add to periodically update the ui ...



Please don't be so lazy and read the docs next time! You know how to write thousands of perfect lines of code, but are you bored of googling the Gtk update rate? Why?

+2


source







All Articles