【问题标题】:Force PyGtk main to redraw强制 PyGtk main 重绘
【发布时间】:2013-01-08 23:28:35
【问题描述】:

我有这样的 UI 结构:
1x Horizo​​ntalBox -> 8x VerticalBox -> 2x Section(GObject) -> 1x RectangleWidget(gtk.DrawingArea)

这只是一个两行 16 个 cairo 矩形的表格。

cairo 矩形小部件本身是 gtk.DrawingArea 的子类,并且有一个暴露处理程序。

我现在重写了程序,数据结构和UI现在完全分开了。有一个线程在后台运行,更新数据结构。在 UI gobject.threads_init() 的前面被调用。在 100 毫秒的超时后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 返回并重绘其他小部件?

【问题讨论】:

    标签: python python-2.7 gtk pygtk gobject


    【解决方案1】:

    试试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,那就更简单了...

    【讨论】:

      【解决方案2】:

      超时 100 毫秒后 gobject.timeout_add(100, self.update_widget)

      尝试在没有 gobject.timeout_add() 的情况下创建 GUI 线程,并在另一个线程中进行所有其他计算。

      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。 如果我正确理解问题,希望这会有所帮助。 :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-16
        • 2015-12-27
        • 1970-01-01
        • 1970-01-01
        • 2023-03-09
        相关资源
        最近更新 更多