2013-01-25 17 views
1

我有一個UI結構是這樣的:
1X Horizo​​ntalBox - > 8倍速VerticalBox - > 2X科(GObject的) - > 1X RectangleWidget(gtk.DrawingArea)力PyGTK的主要重繪

這僅僅是一個表兩排16個開羅矩形。

cairo矩形窗口小部件本身是gtk.DrawingArea的子類並具有一個公開處理程序。

我現在重寫了程序,數據結構和UI現在完全分開了。有一個線程在後臺運行,更新數據結構。在沒有UI gobject.threads_init()被調用。在100ms的超時之後gobject.timeout_add(100, self.update_widget)主發出一個信號,該信號只被第一個小部件接收。

這裏公開處理程序:

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 
#_____________________________________________________________________ 

注:
如果我最小化和還原窗口,窗口小部件收到gsignal並得到更新。

我試過不同的方法。包括線程,不同的信號......所有方法都會導致上述相同的行爲。

如何強制gtk.main返回並重繪其他小部件?

回答

0

100ms的gobject.timeout_add(100,self.update_widget)

儘量使GUI線程而不gobject.timeout_add()和在另一個線程[s]的所有其他計算的超時之後。

gobject.timeout_add看起來像分開的線程和gtk不能正常工作。我的程序的

部分(它的工作原理):

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 

在非主線程牆根所有非GUI操作。主線程 - gui。 希望這有助於如果我正確理解問題。 :)

0

嘗試mainHbox.queue_draw()

如果沒有工作,遍歷所有RectangleWidget對象,並重繪:

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

如果您使用的是Table,這是更簡單...