2014-09-29 4 views
3

Моя программа читается из файла конфигурации. Он загружает виджеты Gtk3 в окне на основе файла конфигурации.Доступ к виджету Gtk3 от его родителя по его имени

Пример файла конфигурации:

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

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

Итак, я сделал класс для моей, например, Виджет типа часов, и я назвал его 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[1] 

    def widget(self): 
     return self.gtkwidget 

Объяснение:

  1. код считывает конфигурационный файл и видит, что он должен создать виджет часов. Таким образом, он создает класс Clock, в котором внутри GtkLabel присутствует переменная. Функция runCommand применит к виджету больше свойств, прочитанных конфигурационным файлом. Например. format Недвижимость для часов.

  2. Функция update запускается каждые 1 секунду из класса WidgetManager, чтобы не обновлять время.

  3. Функция widget(), после того, как добавлено больше команд (свойств) для добавляемого виджета, выполняется, чтобы вернуть GtkWidget и добавить его в главное окно.

Приведенный выше код работает очень хорошо в течение некоторого времени, но после этого метка перестает обновляться в короткое случайное время (1-2 минуты или меньше).

enter image description here

код успешно работать до 18:53:31, а затем метка не обновляется. Я предполагаю, что Gtk внутренне перемещает объект в другую память, и я не могу дольше обращаться к нему со своим старым объектом (?).

Как я могу решить эту проблему? Должен ли я что-то делать по-другому?

Я думал о переходе родительского виджета (который является Gtk.Window подклассом) для ребенка (Clock) и поиска по имени Gtk.Label, который представляет self.gtkwidget (перебор детей?). Итак, получите Gtk.Widget по его названию, отбросьте его до Gtk.Label и вызовите код обновления. Как я могу это реализовать?

С другой стороны, я думаю, что я его переусердствую и, возможно, более простое решение доступно.

EDIT

После некоторых тестов, я решил передать parent в качестве аргумента в конструктор дочернего (виджета) и на 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. адреса памяти виджета на ребенка и на дочернем окне родительского окна совпадают, даже после того, как текст ярлыка имеет sto обновление. Даже тогда оба объекта ссылаются на один и тот же адрес памяти.

  2. Если вы заметили, я вызываю функцию set_text непосредственно от дочернего элемента (с именем childd), и это также не обновляет значение.

Какова вероятность того, что это не ошибка в моем коде, и я должен заставить перерисовать Gtk?

EDIT2

Даже с self.gtkwidget.queue_draw() после set_text, проблема, как представляется, сохранится.

ответ

2

Вы должны будете использовать функцию timeout_add GObject для обновления периодически пользовательского интерфейса ...

Пожалуйста, не настолько ленивы и читать документы в следующий раз! Вы умеете писать тысячи совершенных строк кода, но вам скучно искать в Google периодичность обновления Gtk? Зачем?

+0

Мне нравится пылать эти явно ленивые вопросы, только чтобы узнать, что они мои ;-) –

+0

Ха-ха, усилие, которое я поставил на вопрос, в сравнении с усилиями, которые я вложил в правильные слова, - это ... выдающийся! – hakermania

Смежные вопросы