我有这样的UI结构:
1x HorizontalBox - > 8x VerticalBox - > 2x部分(GObject) - > 1x RectangleWidget(gtk.DrawingArea)
这只是一个包含两行16个开罗矩形的表格。
cairo矩形小部件本身是gtk.DrawingArea的子类,并且有一个expose-handler。
我现在重写了程序,数据结构和UI现在完全分开了。有一个线程在后台运行,更新数据结构。在fornt中调用了UI gobject.threads_init()
。超过100毫秒gobject.timeout_add(100, self.update_widget)
后,主要发出一个信号,该信号仅由第一个小部件接收。
这里是expose-handler:
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 :(得分:2)
尝试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
,那就更容易了......
答案 1 :(得分:0)
超时100ms后gobject.timeout_add(100,self.update_widget)
尝试在没有gobject.timeout_add()的情况下制作GUI线程,并在另一个线程[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动作都隐藏在非主线程中。主线 - 桂。 希望如果我正确理解问题,这会有所帮助:)