0

こんにちは、python と gtk でのプログラミングは初めてです。
私はいくつかの測定を行うためのプログラムを書いています。測定値をプロットするには、matplotlib を使用します。
プログラムには、ヒーターのオン/オフと測定を行う機能が含まれます。
ヒーター用と測定用に別々のスレッドを使用したい。
今のところ、このプログラムではハードウェアとの通信はまだ実装されていません。

問題は、「測定ボタン」をクリックすると、「プログレスバー」が機能しなくなることです。メッセージが表示されます:

0x29b8460 の gtk.ProgressBar オブジェクト (0x0 で初期化されていない)

ヒーターボタンのみを使用すると、プログレスバーが機能し続けます

私は何を間違っていますか?

これがコードです

#!/usr/bin/env python

import pygtk
pygtk.require('2.0')
import gtk
import time
import gobject
import threading
import matplotlib
import numpy as np
from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas

class measure:
    # callback to quit
    def delete_event(self, widget, event, data = None):
        gtk.main_quit()
        return False

    def heater_helper(self, widget, heater, progressbar):
        print "starting heater thread"
        threading.Thread(target=self.heater_cb, args=(widget, heater, progressbar)).start()

    def heater_cb(self, widget, heater, progressbar):
        heaterstring = "6.3"
        heater = eval(heaterstring)
        stap = 1
        j = 0.1
        heatervalue = widget.get_active()
        print heatervalue
        progressbar.set_fraction(0.1)
        while (stap <= 10 ):
            if widget.get_active():
                print widget.get_active()
                fraction = j * stap
                print fraction
                progressbar.set_fraction(fraction)
                stap = stap + 1
                time.sleep(1)
            else:
                stap = 11
                progressbar.set_fraction(0.0)
                break

    def do_measurement_helper(self, widget, fig):
        print " Start measurement thread"
        threading.Thread(target=self.do_measurement, args=(widget, fig)).start()

    def do_measurement(self, widget, fig):
        fig.clear()
        ax = fig.add_subplot(111)
        x = np.arange(0, 5*np.pi, 0.01)
        y = np.sin(x**2)*np.exp(-x)
        ax.plot(x, y)
        fig.canvas.draw()

    def __init__(self):
        # Create new Window
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect("delete_event", self.delete_event)
        self.window.show()

        mainbox = gtk.HBox(False, 0)
        self.window.add(mainbox)
        mainbox.show()

        leftvbox = gtk.VBox(False, spacing = 10)
        mainbox.pack_start(leftvbox, expand = False, fill = False, padding = 0)
        leftvbox.show()

        rightvbox = gtk.VBox(False, spacing = 10)
        mainbox.pack_start(rightvbox, expand = False, fill = False, padding =0)
        rightvbox.show()

        heaterprogressbar = gtk.ProgressBar()
        leftvbox.pack_start(heaterprogressbar, expand = False, fill = False, padding = 0)
        heaterprogressbar.show()
        heaterbutton = gtk.ToggleButton("Heater")
        leftvbox.pack_start(heaterbutton, expand = True, fill = False, padding = 0)
        heaterbutton.show()
        heaterbutton.connect("toggled", self.heater_helper, heaterbutton, heaterprogressbar)

        fig = matplotlib.figure.Figure(figsize=(5,4), dpi=64)
        canvas = FigureCanvas(fig)
        rightvbox.pack_start(canvas, expand = True, fill = True, padding = 0 )
        canvas.show()
        measurebutton = gtk.Button("Measure")
        rightvbox.pack_start(measurebutton, expand = False, fill = False, padding = 0)
        measurebutton.show()
        measurebutton.connect("clicked", self.do_measurement_helper, fig)

def main():
    gtk.main()
    return(0)

if __name__ == "__main__":
    gtk.gdk.threads_init()
    measure()
    main()
    gtk.gdk.threads_leave()

敬具、

ヨリス・ヴァイテルス

4

2 に答える 2

1

スレッド、Matplotlib、および GTK メイン ループの組み合わせはおそらくサポートされておらず、何が起こっているのかを正確にデバッグすることは困難です。私のアドバイスは、スレッドから GUI 呼び出しを行うのではなく、代わりに を使用してスケジュールすることgobject.idle_add()です。

于 2013-04-21T17:45:05.357 に答える