2013-01-25 4 views
1

J'ai une structure de l'interface utilisateur comme ceci:
1x HorizontalBox -> 8 x VerticalBox -> 2x Section (GObject) -> 1x RectangleWidget (gtk.DrawingArea)force PyGtk principale de redessiner

Ceci est simplement une table de 16 rectangles de cairo en deux rangs.

Le widget rectangle cairo lui-même est une sous-classe de gtk.DrawingArea et possède un exposer-handler. Je ai maintenant réécrit le programme, la structure de données et l'interface utilisateur sont maintenant complètement séparés. Un thread s'exécute en arrière-plan, mettant à jour les structures de données. En fornt de l'interface utilisateur gobject.threads_init() est appelée. Après un délai de 100ms gobject.timeout_add(100, self.update_widget) le principal émet un signal, qui est seulement reçu par le premier widget.

Voici l'exposé-gestionnaire:

def OnDraw(self, widget, event):  
    # self.window/widget.window works both 
    ctx = widget.window.cairo_create() 
    ctx.save() 

    rect = self.get_allocation()  
    ctx.rectangle(50, 0, 30, rect.height) 
    ctx.set_source_rgb(*self._BACKGROUND_RGB) 
    ctx.fill() 

    ctx.rectangle(0, rect.height * (1. - self.section.GetLevel()), rect.width, rect.height) 
    ctx.clip()   
    ctx.set_source_surface(self.source, 0, 0) 
    ctx.paint() 
    ctx.restore() 

    return False 
#_____________________________________________________________________ 

def update_widget(self): 
    rect = self.get_allocation()   
    self.window.invalidate_rect(rect, False) 
    while gtk.events_pending(): 
     gtk.main_iteration(False) 
    return True 
#_____________________________________________________________________ 

Note:
Si je réduis et restaurer la fenêtre, les widgets reçoivent le gsignal et obtenir mis à jour.

J'ai essayé différentes approches. Y compris le filetage, la signalisation différente ... Toutes les approches conduisent au même comportement décrit ci-dessus.

Comment puis-je forcer le gtk.main à retourner et redessiner les autres widgets?

Répondre

0

Après un délai d'attente de 100 ms gobject.timeout_add (100, self.update_widget)

Essayez de faire du fil GUI sans gobject.timeout_add() et tous les autres calculs dans un autre thread [s]. Gobject.timeout_add ressemble à un thread séparé et gtk ne peut pas fonctionner normalement avec celui-ci.

Une partie de mon programme (cela fonctionne):

def init_tr_modules(self): 
    window = gtk.Window(gtk.WINDOW_TOPLEVEL) 
    window.set_title("Checking internet connection") 
    window.set_border_width(2) 
    window.set_icon(app_gui.icon) 
    window.set_geometry_hints(None, 510, 27) 
    vbox = gtk.VBox(False, 1) 
    vbox.set_border_width(1) 
    window.add(vbox) 
    pbar = gtk.ProgressBar() 
    vbox.pack_start(pbar, False, False, 1) 
    window.set_position(gtk.WIN_POS_CENTER) 
    window.set_resizable(False) 
    pbar.set_text("Wait") 
    pbar.set_pulse_step(0.01) 
    window.show_all() 
    tr_thread = \ 
     threading.Thread(target = self.init_tr_services) 
    tr_thread.start() 
    while self.queue.qsize() == 0: 
     while gtk.events_pending(): 
      gtk.main_iteration(False) 
     pbar.pulse() 
     sleep(0.05) 
    while self.queue.qsize(): 
     self.queue.get() 
    window.set_title("Get list") 
    pbar.set_fraction(0.005) 
    while gtk.events_pending(): 
     gtk.main_iteration(False) 
    for i in self.tr_services: 
     pbar.set_text(i.service.get_service_name()) 
     tr_thread = \ 
      threading.Thread(target = i.service.renew_list) 
     tr_thread.start() 
     while self.queue.qsize() == 0: 
      while gtk.events_pending(): 
       gtk.main_iteration(False) 
     while self.queue.qsize(): 
      self.queue.get() 
     new_val = pbar.get_fraction() + (1.0-0.006)/len(self.tr_services) 
     pbar.set_fraction(new_val) 
    window.destroy() 
#end def 

Toutes les actions non-hided en fil interface utilisateur graphique non principal. Fil principal - gui. J'espère que cela aide si je comprends bien la question. :)

0

Essayez mainHbox.queue_draw()

Si cela ne fonctionne pas, itérer sur tous les objets RectangleWidget et redessiner:

for vbox in mainHbox.get_children(): 
    for hbox in vbox.get_children(): 
     for widget in hbox.get_children(): 
      widget.queue_draw() 

Et si vous utilisez un Table, qui est encore plus facile ...

Questions connexes