Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python QTimer不´;t调用该方法来设置绘图动画_Python_Multithreading_Sockets_Pyqt5_Qthread - Fatal编程技术网

Python QTimer不´;t调用该方法来设置绘图动画

Python QTimer不´;t调用该方法来设置绘图动画,python,multithreading,sockets,pyqt5,qthread,Python,Multithreading,Sockets,Pyqt5,Qthread,我正在尝试在PyQt5中创建一个GUI应用程序,该应用程序连续接收来自远程GUI的数据,并使用pyqtgraph绘制一个动画。 我正在使用Python套接字模块进行连接和传输数据。我正在为GUI和连接使用多线程 GUI和数据的接收工作正常,但在处理接收到的数据进行绘图时,Qtimer不会调用制作动画的方法 import sys import time from PyQt5 import QtCore, QtGui, QtWidgets, uic from PyQt5.QtWidgets impo

我正在尝试在PyQt5中创建一个GUI应用程序,该应用程序连续接收来自远程GUI的数据,并使用pyqtgraph绘制一个动画。 我正在使用Python套接字模块进行连接和传输数据。我正在为GUI和连接使用多线程

GUI和数据的接收工作正常,但在处理接收到的数据进行绘图时,Qtimer不会调用制作动画的方法

import sys
import time
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.uic import loadUi
from PyQt5.QtCore import QTimer
import socket 
from threading import Thread 
from socketserver import ThreadingMixIn 
import numpy as np
import pyqtgraph as pg

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        loadUi('app.ui', self)       
        self.plotWidget.plotItem.showGrid(True, True, 0.2)
        self.serverThread=ServerThread()
        self.serverThread.start()

    def plot(self, amplitude):
        self.y = amplitude * np.random.normal(size=600)
        self.plotWidget.setXRange (0, 2)
        self.plotWidget.setYRange (-0.5, 1)
        Color = pg.mkPen('g', width=1)
        self.curve = self.plotWidget.plot(self.y, pen=Color)
        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.update)
        self.timer.start(20)

    #method that performs the animation
    def update(self):
        self.y[:-1] = self.y[1:]  # shift data in the array one sample left
        self.curve.setData(self.y)

class ServerThread(Thread):
    def __init__(self): 
        Thread.__init__(self) 
        self.window=window

     def run(self): 
        TCP_IP = '0.0.0.0' 
        TCP_PORT = 5000 
        BUFFER_SIZE = 20  
        tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
        tcpServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
        tcpServer.bind((TCP_IP, TCP_PORT)) 
        threads = [] 

        tcpServer.listen(1) 
        while True:
            print("Multithreaded Python server : Waiting for connections from TCP clients..") 
            global conn
            (conn, (ip,port)) = tcpServer.accept() 
            newthread = ClientThread(ip,port) 
            newthread.start() 
            threads.append(newthread) 

        for t in threads: 
            t.join()

class ClientThread(Thread): 
    def __init__(self,ip,port): 
        Thread.__init__(self) 
        self.ip = ip 
        self.port = port 
        print("[+] New server socket thread started for " + ip + ":" + str(port))

    def run(self):        
        while True :             
            global conn
            data = conn.recv(2048)
            data_recv = data.decode('utf-8')
            data = int (data_recv)
            window.plot(data)


if __name__ == '__main__':
    app = QApplication(sys.argv)        
    window = Window()
    window.show()  
    sys.exit(app.exec_())
GUI显示不带动画的绘图。有什么问题吗?进程是否被阻止?正在对QThread中的QTimer进行垃圾收集?我做错了什么


如果有人有想法,请帮助我。

我认为问题在于,您直接从非主/GUI线程的线程调用
window.plot(data)
,并期望QTimer随后在主/GUI线程中调用slot方法

但是,Qt不是这样工作的——如果希望
QTimer
在主线程中工作,则需要在主线程中创建它

第二个问题是,您在每次调用
window.plot(data)
时都要创建一个新的
QTimer
,并将每个新的
QTimer
设置为每20mS发出一个信号。因此,即使
QTimer
功能正常工作,数十个/数百个
QTimer
对象的稳定累积(每个对象每秒发出50次信号)也会很快使程序变得无用

我的修复建议是只创建一个
QTimer
对象(可能在
窗口内。
初始化(self)),
connect()
将其连接到
update()
插槽,并对其调用
start(20)
;这将足以让您的
self.update()
方法在50Hz(CPU功率允许)时被调用


这只剩下一个问题,即如何将接收到的
数据
从网络线程安全地传输到主线程。为此,最简单的方法可能是创建
QEvent
的子类,该子类可以将收到的
数据作为成员变量保存,并让您的网络线程在每次需要向主线程发送
数据时创建该子类的新对象,并调用
QApplication.postEvent()
使用
窗口和
QEvent
-对象作为参数。然后在
窗口中
类中,重写
事件(self,QEvent)
方法(当窗口对象接收到任何事件时调用该方法),并在其中添加逻辑,以便如果事件参数是事件子类之一,它将从事件中获取
数据
,并对其进行处理。(这里的关键优势是,
event(self,QEvent)
由主线程调用,而不是直接由网络线程调用,因此您可以在该上下文中安全地与主线程/GUI对象交互)

我认为问题在于您直接调用的是
window.plot(数据)
来自非主/GUI线程的线程,并期望QTimer随后在主/GUI线程中调用slot方法

但是,Qt不是这样工作的——如果希望
QTimer
在主线程中工作,则需要在主线程中创建它

第二个问题是,您在每次调用
window.plot(data)
时都要创建一个新的
QTimer
,并将每个新的
QTimer
设置为每20mS发出一个信号。因此,即使
QTimer
功能正常工作,数十个/数百个
QTimer
对象的稳定累积(每个对象每秒发出50次信号)也会很快使程序变得无用

我的修复建议是只创建一个
QTimer
对象(可能在
窗口内。
初始化(self)
),
connect()
将其连接到
update()
插槽,并对其调用
start(20)
;这将足以让您的
self.update()
方法在50Hz(CPU功率允许)时被调用

这只剩下一个问题,即如何将接收到的
数据
从网络线程安全地传输到主线程。为此,最简单的方法可能是创建
QEvent
的子类,该子类可以将收到的
数据作为成员变量保存,并让您的网络线程在每次需要向主线程发送
数据时创建该子类的新对象,并调用
QApplication.postEvent()
使用
窗口和
QEvent
-对象作为参数。然后在
窗口中
类中,重写
事件(self,QEvent)
方法(当窗口对象接收到任何事件时调用该方法),并在其中添加逻辑,以便如果事件参数是事件子类之一,它将从事件中获取
数据
,并对其进行处理。(这里的关键优势是
事件(self,QEvent)
由主线程调用,而不是直接由网络线程调用,因此您可以在该上下文中安全地与主线程/GUI对象交互)