2017-09-04 13 views
0

添付のプログラムは、これらのエラーをスローすることは、GUIスレッドPySide/PyQtGraphアクセスが

QObjectの外ピックスマップを使用することは安全ではありません:: startTimer:タイマーから起動することはできません別のスレッド

import sys 
import PySide 
import numpy as np 
import pyqtgraph as pg 
import threading 

from PySide import QtGui, QtCore 
from PySide.QtGui import * 
from PySide.QtCore import * 
from ui_mainWindow import Ui_MainWindow 

#------------------------------------------------------------------------------- 
# Main Window Class 
# handle events and updates to the Qt user interface objects 
#------------------------------------------------------------------------------- 
class MainWindow(QMainWindow, Ui_MainWindow): 

    def __init__(self): 
     super(MainWindow, self).__init__() 
     self.setupUi(self) 
     self.setup_actions() 
     self.show() 

    def setup_actions(self): 
     self.startScopeButton.clicked.connect(self.start_stop_scope) 

    def start_stop_scope(self): 
     print("starting scope") 
     self.scope_display_thread() 

    def scope_display_thread(self): 
     threading.Thread(target=self._scope_display_thread).start() 

    def _scope_display_thread(self): 
     global data_ch1  
     data_ch1 = np.random.normal(0, 10, 1000) 
     self.graphicsView.plot(data_ch1,clear=True) 

#------------------------------------------------------------------------------- 
# Main Application Start Point 
#------------------------------------------------------------------------------- 

def main(): 
    app = QApplication(sys.argv) 
    mainWin = MainWindow() 
    ret = app.exec_() 
    sys.exit(ret) 

data_ch1 = [] 
main() 

これは私がやろうとしているものの単純化バージョンです。つまり、1つのスレッドが受信し、プロットデータを持っています。フォーラムなどを検索することから、私は根本的に問題があることを知っています。私は "メインのQtイベントスレッド"からプロットを更新する必要があります。しかし、これを達成する方法はわかりません。私のコードのいくつかのシグナルスロット置換は有望に見えましたが、プログラムがクラッシュするだけでした。

私は改革されたC#人です;-) C#またはJavaでは、通常、私は実際にペイントメソッドオーバーライドで描画を行い、新しいデータがあったときにアプリケーションを再描画するように強制します。 PyQtGraph.plot()がすぐにペイントしようとしたようですね??データを非同期的に追加してから、メインスレッドにシーンの再描画を指示することはできますか?

ありがとうございました!

+0

'graphicsView'は何ですか? – eyllanesc

答えて

0

あなたの質問にコメントしても、メインスレッドのGUIのみを更新できます。このタイプの問題の戦略は、セカンダリスレッドのデータをメインスルー信号に送信することです。 np.random.normal (0, 10, 1000)が、これは簡単にすることによって得ることができるnp.ndarrayされ、あなたの特定のケースで

signal = QtCore.Signal(type_1, type_2, ..., type_n) 

信号は、いくつかのデータを運ぶことができるが、これらは、その作成に示されなければならない、それを作成する方法は以下のとおりです。次のコマンドを実行:

print(type(np.random.normal (0, 10, 1000))) 

出力:

<class 'numpy.ndarray'> 

objectは、すべてのクラスがその基本クラスから継承するため使用できます。その後、我々は、以下に示すようにプロットは、このケースでは、我々はラムダ関数を使用する機能と、その信号を接続します

class MainWindow(QtGui.QMainWindow, Ui_MainWindow): 
    signal = QtCore.Signal(np.ndarray) # or signal = QtCore.Signal(object) 

    def __init__(self): 
     [..] 
     self.show() 

     self.signal.connect(lambda data: self.graphicsView.plot(data, clear=True)) 

    [...] 

    def _scope_display_thread(self): 
     data_ch1 = np.random.normal(0, 10, 1000) 
     self.signal.emit(data_ch1) 
+0

優れています。助けてくれてありがとう。私はこれが他の人たちにも役立つと感じています。私が基本的な問題を理解していても、正しい方法を見つけることは、野生のガチョウの追跡であった。 –

+0

私の答えを正しいものとして忘れずにマークしてください – eyllanesc