【发布时间】:2021-10-17 10:11:05
【问题描述】:
我正在处理我的第一个应用程序。在一个窗口中,我有一个按钮,单击该按钮时,我想从另一个模块执行一个方法。此方法执行时间不确定,并且取决于终端中的用户输入。此方法创建一个文件并重复打开它,将内容写入文件,然后关闭文件。在此运行的同时,我在窗口中有一个 matplotlib 图形小部件,每次通过读取和绘制文件最新行中的数据将新内容写入文件时,我想更新一个绘图。
据我了解,如果我让它在我的 QT 程序的主线程中运行,我的应用程序中的任何内容都不会响应,直到用户输入函数完成。为了解决这个问题,我尝试将用户输入法的执行移到工作线程中。以我这样做的方式,我不相信它正在工作。作为一项测试,我尝试制作一个 QTimer,它试图读取文件并每秒绘制一次(添加一些东西来检查文件是否存在)。这会打印出文件在长任务之前还不存在,然后什么也不做,直到长任务完成,然后每秒开始读取和绘制文件。我不确定这是否意味着我没有正确处理线程或是否发生了其他事情。
为了检查文件的更改,我尝试使用 QFileSystemWatcher。更新:现在,在 userInputFunction() 运行时没有任何反应,但是当它完成时,我得到“data/runName_Rec.txt dataFileCreated”。如果我随后以任何方式手动编辑文件,则绘图会按原样进行。但我仍然想正确地线程化它,以便在我运行 userInputFunction() 时观察者工作
这是我的代码相关部分的简化示例。对于任何不良风格问题,我们深表歉意。
from PyQt5 import QtWidgets, uic, QtCore, QtGui
from pyqtgraph import PlotWidget
from PyQt5.QtCore import QObject, QThread, pyqtSignal
import pyqtgraph as pg
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QInputDialog, QLineEdit, QFileDialog, QMainWindow
import os
from os.path import exists
import csv
import numpy as np
import pandas as pd
import myModule
dirname = os.path.dirname(__file__)
class Worker(QObject):
finished = pyqtSignal()
def run(self,param1,param2):
"""Long-running task with user input from terminal."""
myModule.userInputFunction(param1,param2)
self.finished.emit()
class someWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super(someWindow, self).__init__(*args, **kwargs)
#Load the UI Page
uic.loadUi('somewindow.ui', self)
self.directoryPath = "data"
self.fs_watcher = QtCore.QFileSystemWatcher()
self.fs_watcher.addPath(self.directoryPath)
self.fs_watcher.directoryChanged.connect(self.dataFileCreated)
self.StartScanButton.clicked.connect(self.startSliceScan)
self.EndScanButton.clicked.connect(self.endScan)
def dataFileCreated(self):
self.filePath = os.path.join(dirname, "data/"+ self.runNameBox.toPlainText()+"_Rec.txt")
print(self.filePath + " dataFileCreated")
self.fs_watcher.addPath(self.filePath)
self.fs_watcher.fileChanged.connect(self.update_graph)
def update_graph(self):
if exists(self.path):
print("file exists!")
#then read the filePath.txt and plots the data
else:
print("file doesn't exist yet")
def endScan(self):
#change some display things
def runLongTask(self):
# Step 2: Create a QThread object
self.thread = QThread()
# Step 3: Create a worker object
self.worker = Worker()
# Step 4: Move worker to the thread
self.worker.moveToThread(self.thread)
# Step 5: Connect signals and slots
self.thread.started.connect(self.worker.run(param1,param2))
self.worker.finished.connect(self.thread.quit)
self.worker.finished.connect(self.worker.deleteLater)
self.thread.finished.connect(self.thread.deleteLater)
# Step 6: Start the thread
self.thread.start()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = someWindow()
w.show()
sys.exit(app.exec_())
【问题讨论】:
标签: python multithreading pyqt5