#python #multithreading #pyqt5
#python #многопоточность #pyqt5
Вопрос:
Это мой код. Он имитирует сигнал, который я получаю от осциллографа. Я пытаюсь создать интерфейс, но я новичок в программировании (и английском языке), и у меня возникли некоторые проблемы.
я уже создаю график графика в реальном времени и кнопку, но при нажатии сигнал перестает обновляться, и я просто получаю один и тот же сигнал снова и снова. Мне просто нужно знать, как постоянно обновлять сигнал, пока я нахожусь в цикле, если это возможно.
import pyqtgraph as pg
import numpy as np
import sys
from PyQt5 import QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QThread, pyqtSignal
class plotarT(QThread):
signal = pyqtSignal(object)
def __init__(self):
QThread.__init__(self)
self.phase = 0
def __del__(self):
self.wait()
def update(self):
self.t = np.arange(0, 3.0, 0.01)
self.s = np.sin(2 * np.pi * self.t self.phase) #sin function
self.phase = 0.1
QThread.msleep(2500) #To simulate the time that oscilloscope take to respond
def run(self):
while True:
self.update()
self.signal.emit(self.s) #this emit the vectors
class Window(QDialog):
def __init__(self):
self.app = QtGui.QApplication(sys.argv)
super().__init__()
self.title = "PyQt5 GridLayout"
self.top = 100
self.left = 100
self.width = 1000
self.height = 600
self.InitWindow()
self.traces = dict()
pg.setConfigOptions(antialias=True)
def InitWindow(self):
self.setWindowIcon(QtGui.QIcon("icon.png"))
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.gridLayoutCreation()
vboxLayout = QVBoxLayout()
vboxLayout.addWidget(self.groupBox)
self.setLayout(vboxLayout)
self.show()
def gridLayoutCreation(self): #my interface
self.groupBox = QGroupBox("Grid Layout Example")
gridLayout = QGridLayout()
self.guiplot = pg.PlotWidget()
gridLayout.addWidget(self.guiplot,0,8,8,12)
BtnL = QPushButton('Test')
gridLayout.addWidget(BtnL, 0, 1)
self.tlg = QLineEdit('')
gridLayout.addWidget(self.tlg, 1,1)
self.groupBox.setLayout(gridLayout)
BtnL.clicked.connect(self.get_data)
def get_data(self):
raw1 = []
raw2 = []
for i in range(2): #the signal does not update while running the loop
raw1.append(self.s)
time.sleep(1)
print(self.s)
def plotar(self,s): #here i plot the vector
self.s = s
self.guiplot.clear()
self.guiplot.plot(s)
def teste(self):
self.get_thread = plotarT()
self.get_thread.signal.connect(self.plotar) #connect to function
self.get_thread.start()
def main():
app = QtGui.QApplication(sys.argv)
form = Window()
form.show()
form.teste()
app.exec_()
if __name__ == '__main__': #Run my aplicattion
main()
Комментарии:
1. Я не вижу никакой проблемы в логике вашего кода, я вижу только много опечаток, поэтому она не заслуживает ответа в SO, поэтому я создал суть с полным решением gist.github.com/eyllanesc/c242051ced9402bd01dea30fcedb33f6
2. Я не знаю, как начать создавать функциональную кнопку. Это работает гладко, но кнопка «test», которую я создал, бесполезна, и я не знаю, как заставить ее работать.
Ответ №1:
Попробуйте:
import pyqtgraph as pg
import numpy as np
import sys
from PyQt5 import QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QThread, pyqtSignal, QTimer # QTimer
class plotarT(QThread):
signal = pyqtSignal(object)
def __init__(self):
QThread.__init__(self)
self.phase = 0
def __del__(self):
self.wait()
def update(self):
self.t = np.arange(0, 3.0, 0.01)
self.s = np.sin(2 * np.pi * self.t self.phase) #sin function
self.phase = 0.1
QThread.msleep(500) # 500
def run(self):
while True:
self.update()
self.signal.emit(self.s) #this emit the vectors
class Window(QDialog):
def __init__(self):
self.app = QtGui.QApplication(sys.argv)
super().__init__()
self.title = "PyQt5 GridLayout"
self.top = 100
self.left = 100
self.width = 1000
self.height = 600
self.InitWindow()
self.traces = dict()
pg.setConfigOptions(antialias=True)
self.timer = QTimer(self, timeout=self.pipe_output, interval=1000) #
def InitWindow(self):
self.setWindowIcon(QtGui.QIcon("icon.png"))
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.gridLayoutCreation()
vboxLayout = QVBoxLayout()
vboxLayout.addWidget(self.groupBox)
self.setLayout(vboxLayout)
self.show()
def gridLayoutCreation(self): #my interface
self.groupBox = QGroupBox("Grid Layout Example")
gridLayout = QGridLayout()
self.guiplot = pg.PlotWidget()
gridLayout.addWidget(self.guiplot,0,8,8,12)
BtnL = QPushButton('Test')
gridLayout.addWidget(BtnL, 0, 1)
self.tlg = QLineEdit('')
gridLayout.addWidget(self.tlg, 1,1)
self.groupBox.setLayout(gridLayout)
BtnL.clicked.connect(self.get_data)
def get_data(self):
# raw1 = []
# raw2 = []
# for i in range(2): #the signal does not update while running the loop
# raw1.append(self.s)
# time.sleep(1)
# print(self.s)
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
self.timer.start()
self.raw1 = []
self.raw2 = []
self.i = 0
def pipe_output(self):
self.i = 1
self.raw1.append(self.s)
print("n ----------- n", self.s)
if self.i == 2:
self.timer.stop()
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
def plotar(self, s): # here i plot the vector
print("def plotar(self, s):", type(s))
self.s = s
self.guiplot.clear()
self.guiplot.plot(self.s) #(s)
def teste(self):
self.get_thread = plotarT()
self.get_thread.signal.connect(self.plotar) #connect to function
self.get_thread.start()
def main():
app = QtGui.QApplication(sys.argv)
form = Window()
form.show()
form.teste()
app.exec_()
if __name__ == '__main__': #Run my aplicattion
main()