DHT11温度センサーから値を取得しようとしていて、3つのボタンを持つGUIメインウィジェットにプロットしています。センサーから値を取得し始め、2番目はリアルタイムで値をプロットし、3番目の値は値のFFTをプロットすることです。RuntimeError:メインスレッドがメインループにありません - 2つの図でプロットしています
私はボタンをプロットFFTを押したときに、私はplt.figure(2)
にdef plotFFTButton_clicked(self):
下plt.figure(1)
を変更するたびに、私はfolowingエラーを取得するため、問題は、私はリアルタイムプロットと2つの図にFFTプロットをsaperateことができないということです。 はRuntimeError:メインスレッドはメインループ
他の問題ではありませんが、それは私に同じエラーを与えるので、私はdef runValue(self):
下plt.figure(1)
を削除することはできませんということです。
誰かが私のコードで問題を見つけるのを助けることができたら、私は感謝します。
from PyQt4 import QtCore, QtGui
import sys
import time
from threading import Event, Thread
from mainwindow import Ui_MainWindow
from PyQt4.Qt import QString, QFileDialog
from pylab import *
import threading
from threading import Thread
#DH11 tempSensor Library
import Adafruit_DHT
#Library to find FFT and FFTshift
from scipy.fftpack import fft, fftshift
from numpy import linspace
class dataAcquisition(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(dataAcquisition, self).__init__(parent)
self.setupUi(self)
self.startButton.clicked.connect(self.startButton_clicked)
self.th = Thread(target = self.runValue)
self.plotRTButton.clicked.connect(self.plotRTButton_clicked)
self.plotFFTButton.clicked.connect(self.plotFFTButton_clicked)
self.Value = 0.0
self.X = 0.0
self.Y = 0.0
self.ChageValueState = False
def runValue(self):
self.X = []
self.Y = []
i = 0.0
plt.figure(1) #an error comes out if I delete this
while True:
self.ChageValueState = True
self.Value = Adafruit_DHT.read_retry(11, 4)[1] #Or you could give the self.Value any number
i += 0.10
self.X.append(i)
self.Y.append(self.Value)
pause(0.01)
def startButton_clicked(self):
self.th.start()
def plotRTButton_clicked(self):
plt.figure(1)
ax1 = subplot(3, 1, 1)
Line1 = plot(0,0,'r-')[0]
Line1.set_xdata(self.X)
Line1.set_ydata(self.Y)
ax1.relim()
ax1.autoscale_view()
def plotFFTButton_clicked(self):
Fs = 8000
N = 256
f = linspace(-Fs/2, Fs/2, N)
plt.figure(1) #an error comes out if I plot in a new figure
ax2 = plt.subplot(3, 1, 2)
Line2 = plot(f,0*f,'r-')[0]
FFT = log10(abs(fft(self.Y, N)))
FFT = fftshift(FFT)
Line2.set_ydata(FFT)
ax2.relim()
ax2.autoscale_view()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
MainWindow = dataAcquisition()
MainWindow.show()
sys.exit(app.exec_())
問題は、グラフィックスレッドの関数を別のスレッドから直接呼び出してしまうことです。グラフィックスレッドにキューを与え、GUIスレッドから直接関数を呼び出すのではなく、そのキューにイベントを入れます。スレッド自体のキューを読み取り、独自のスレッドからの呼び出しによって各グラフのプロットを開始します。 –
私はPythonの初心者であるので、キューの使い方を教えてください。 –
すべてのQt GUI操作(プロットを含む)は、メインスレッドで行う必要があります。セカンダリスレッドからのプロットは禁止されています。セカンダリスレッドでデータを取得できますが、プロットするにはGUIスレッドに戻す必要があります。通常、 'QThread'とQtのシグナルとスロットのメカニズムを使って、安全にデータを渡します。スレッド間でデータを渡す方法と 'QThread'を使う方法については、スタックオーバーフローに関する多くのpyqtの例があります。 –