Как мне создать кнопку, чтобы получать следующие обновления сигнала в PyQt5?

#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()