2

私は次のようなUI構造を持っています:
1x水平ボックス->8x垂直ボックス->2xセクション(GObject)-> 1x RectangleWidget(gtk.DrawingArea)

これは、2行に16個のカイロ長方形のテーブルです。

cairo長方形ウィジェット自体は、gtk.DrawingAreaのサブクラスであり、expose-handlerを備えています。

プログラムを書き直したところ、データ構造とUIが完全に分離されました。バックグラウンドで実行されているスレッドがあり、データ構造を更新しています。UIのforntでgobject.threads_init()呼び出されます。100msgobject.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に他のウィジェットを返して再描画させるにはどうすればよいですか?

4

2 に答える 2

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、さらに簡単です...

于 2013-07-29T17:58:40.437 に答える
0

100ms のタイムアウト後 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。質問を正しく理解できれば、これが役立つことを願っています。:)

于 2013-07-09T08:56:13.073 に答える