附加程序会抛出这些错误:
QPixmap:在GUI线程之外使用pixmaps是不安全的
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()
这是我尝试做的简化版本..即有一个线程接收并绘制数据。通过搜索论坛等我从根本上知道问题是我必须从"主要Qt事件线程更新剧情" ..但我不知道如何做到这一点。我的代码的几个信号槽排列看起来很有希望,但只会导致程序崩溃。
请放轻松我,我已经改造了C#person ;-)在C#或Java中,我实际上是在绘制方法覆盖中进行绘制,然后强制应用程序在重新绘制时重新绘制数据被加载。似乎PyQtGraph.plot()试图立即绘制?我可以异步添加数据然后告诉主线程重新绘制场景吗?
谢谢!
答案 0 :(得分:1)
当您评论您的问题时,您只能更新主线程中的GUI,然后此类问题的策略是通过信号将辅助线程的数据发送到主要。
信号可以携带多个数据,但必须在创建时指出这些数据,创建它的方式如下:
signal = QtCore.Signal(type_1, type_2, ..., type_n)
在您的特定情况np.random.normal (0, 10, 1000)
为np.ndarray
时,可以通过执行以下操作轻松获得:
print(type(np.random.normal (0, 10, 1000)))
输出:
<class 'numpy.ndarray'>
或者我们可以使用object
,因为所有类都继承自该基类。然后我们将该信号与绘图函数连接起来,在这种情况下我们将使用lambda函数,如下所示:
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)