python - 如何将 QWidget 类中的 lineedit 字符串共享到工作线程
问题描述
现在我有一个 GUI 窗口,它接受几行用户输入并将它们插入到另一个导入的脚本的函数中。我需要在这个过程中添加线程,因为我将用户输入插入的功能可能需要很长时间并导致 GUI 变得无响应。这个 GUI 有一个主窗口和几个继承自 QWidget 类的其他窗口。下面显示的是我的导入和接受输入的窗口的代码。
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5.QtWidgets import QInputDialog, QFileDialog, QDialog
from PyQt5 import QtGui
from PyQt5.QtCore import Qt, QObject, QThread, pyqtSignal
import geopandas as gpd
from aw_widget import Ui_Areal_Weight
from areal_weight import arealwt
class aw(qtw.QWidget):
def __init__(self):
super().__init__()
self.ui = Ui_Areal_Weight()
self.ui.setupUi(self)
self.ui.aw_source_browse.clicked.connect(self.source_browser)
self.ui.aw_target_browse.clicked.connect(self.target_browser)
self.ui.aw_save_browse.clicked.connect(self.save_browser)
self.ui.aw_run_prog.clicked.connect(self.run_aw)
self.ui.aw_cancel_prog.clicked.connect(self.close_aw)
title = "Areal Weighting Method"
self.setWindowTitle(title)
def source_browser(self):
self.filename = QFileDialog.getOpenFileName()
self.ui.aw_source_lineedit.setText(self.filename[0])
def target_browser(self):
self.filename = QFileDialog.getOpenFileName()
self.ui.aw_target_lineedit.setText(self.filename[0])
def save_browser(self):
self.filename = QFileDialog.getSaveFileName()
self.ui.aw_save_lineedit.setText(self.filename[0])
def run_aw(self):
src = self.ui.aw_source_lineedit.text()
target = self.ui.aw_target_lineedit.text()
intp = self.ui.aw_intp_fields.text()
intp = intp.split()
suffix = self.ui.aw_output_suffix.text()
save = self.ui.aw_save_lineedit.text()
try:
src = gpd.read_file(src)
except:
qtw.QMessageBox.critical(self, 'Error', 'Invalid Source Shapefile')
raise
try:
target = gpd.read_file(target)
except:
qtw.QMessageBox.critical(self, 'Error', 'Invalid Target Shapefile')
raise
try:
outp = arealwt(src, target, intp, suffix)
outp.to_file(save)
qtw.QMessageBox.information(self, 'Success', 'Areal Weighting Complete')
except:
qtw.QMessageBox.critical(self, 'Error', 'Interpolation Failed')
raise
def close_aw(self):
self.close()
我的第一直觉是将 run_aw() 函数的内容移动到 aw 类之外的工作线程,但我不确定如何将 GUI 中的 lineedits 中的字符串共享给工作类,以便我可以插入将它们放入我的 areawt() 函数的参数中。基本上我希望用户填写所有字段,然后当他们单击运行时,lineedit 数据被发送到工作人员类并插入到 arealwt() 函数的参数中。在我看到的 QThread 示例中,需要很长时间处理的主函数被移至工作线程,但我还没有看到该函数依赖于用户输入 GUI 的信息的示例。
我的问题是,如何将 lineedit 字符串数据从我的 GUI 窗口发送到工作线程?
解决方案
我能够通过从我的主类发出一个信号来解决这个问题,该信号包含我想传递给工人类的变量。我在工人类的函数中添加了一个装饰器,以便它可以接受字符串作为参数。
class aw_Worker(qtc.QObject):
finished = qtc.pyqtSignal()
@qtc.pyqtSlot(str,str,list,str,str)
def worker_func(self, src, target, intp, suffix, save):
src = gpd.read_file(src)
target = gpd.read_file(target)
outp = arealwt(src, target, intp, suffix)
outp.to_file(save)
self.finished.emit()
class aw(qtw.QWidget):
worker_requested = qtc.pyqtSignal(str,str,list,str,str)
def __init__(self):
super().__init__()
self.ui = Ui_Areal_Weight()
self.ui.setupUi(self)
self.ui.aw_source_browse.clicked.connect(self.source_browser)
self.ui.aw_target_browse.clicked.connect(self.target_browser)
self.ui.aw_save_browse.clicked.connect(self.save_browser)
self.ui.aw_run_prog.clicked.connect(self.run_aw)
self.ui.aw_cancel_prog.clicked.connect(self.close_aw)
title = "Areal Weighting Method"
self.setWindowTitle(title)
def source_browser(self):
self.filename = QFileDialog.getOpenFileName()
self.ui.aw_source_lineedit.setText(self.filename[0])
def target_browser(self):
self.filename = QFileDialog.getOpenFileName()
self.ui.aw_target_lineedit.setText(self.filename[0])
def save_browser(self):
self.filename = QFileDialog.getSaveFileName()
self.ui.aw_save_lineedit.setText(self.filename[0])
def run_aw(self):
# get data from gui
src = self.ui.aw_source_lineedit.text()
target = self.ui.aw_target_lineedit.text()
intp = self.ui.aw_intp_fields.text()
intp = intp.split()
suffix = self.ui.aw_output_suffix.text()
save = self.ui.aw_save_lineedit.text()
# create thread
self.thread = qtc.QThread()
# create worker
self.worker = aw_Worker()
# move worker to thread
self.worker.moveToThread(self.thread)
# connect signals and slots
self.worker_requested.connect(self.worker.worker_func)
self.worker.finished.connect(self.thread.quit)
# start thread
self.thread.start()
# send data
self.worker_requested.emit(src,target,intp,suffix,save)
推荐阅读
- apache-kafka - 架构注册表:部分共享/授权系统
- spring - 即使我不想加载弹簧存储库EntityGraph JoinFormula Lazy
- python-2.7 - 读取在线资产的图像大小时完成时间不稳定(使用 Python 和请求)
- php - php - 在 Do.. 中按列分组
- javascript - 退出 While 控制器后重置 JSON 提取器参数值 - JMeter
- mysql - MySQL 数据库保留历史更改(如 wiki)
- spring-boot - Spring Boot 应用程序:如何修复 js 更改
- php - 随机文件名
- networking - XPS 已启用并已配置,但是不会调用 get_xps_queue() 函数来选择 tx 队列
- automated-tests - 在 Katalon Studio 中找不到“全局变量视图”