我正在使用 PyQT5 构建 Windows 10 GUI。该应用程序允许用户单击按钮,选择包含一堆文件名的 XML 文件,然后从这些名称创建 ZIP 文件。
我有一个没有 GUI 的简单 Python 脚本。
添加PyQT5 GUI时出现问题。我正在使用 QT listWidget 来显示 XML 文件中包含的文件名。主窗口中的按钮按下事件调用函数“A”来提示用户输入 XML 文件并填充 QT listWidget。
如果我将创建 ZIP 文件的代码添加到结束函数“A”中,一切正常,但 QT listWidget 长时间保持空白,使得程序看起来没有响应。 (显然没有办法在函数完成之前更新、重画或刷新 QT listWidget。)
我想调用函数“A”来获取 XML 文件并填充 QT listWidget,然后调用函数“B”来创建 ZIP 文件。
如何在功能“A”完成后才执行功能“B”?
最小可重现代码是
# Python script to read HEC-RAS RasMapper (*.rasmapper) file and create a single zip file of all applicable related files and directories.
import tkinter as tk
from tkinter import filedialog
import os
from pathlib import Path
from zipfile import ZipFile
from xml.etree import ElementTree as ET
import re
global FilesToPack, RASpath
#The code below was generated by QT Designer////////////////////////
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1000, 700)
MainWindow.setMinimumSize(QtCore.QSize(1200, 700))
MainWindow.setMaximumSize(QtCore.QSize(3000, 2000))
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.formLayout = QtWidgets.QFormLayout(self.centralwidget)
self.formLayout.setObjectName("formLayout")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setMinimumSize(QtCore.QSize(200, 0))
self.pushButton.setBaseSize(QtCore.QSize(0, 0))
self.pushButton.setObjectName("pushButton")
self.pushButton.setText("Begin Packing")
self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.pushButton)
self.listWidget = QtWidgets.QListWidget(self.centralwidget)
self.listWidget.setObjectName("listWidget")
self.formLayout.setWidget(5, QtWidgets.QFormLayout.SpanningRole, self.listWidget)
MainWindow.setCentralWidget(self.centralwidget)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
#The code above was generated by QT Designer////////////////////////
root = tk.Tk()
root.withdraw()
self.pushButton.clicked.connect(self.PackingProcess)
self.PackFile() #Need this function to execute only after PackingProcess function has set FilesToPack and RASpath
def PackingProcess(self):
self.listWidget.clear()
RASmapfile = filedialog.askopenfilename(title="Select the HEC-RAS RasMapper file to process", filetypes=[("RasMapper file","*.rasmap")])
self.listWidget.addItem(RASmapfile)
RASpath = str(Path(RASmapfile).parent)
# Using dummy filenames here for Minimum Reproducible Code to avoid having to post large data files
FilesToPack = ["File1", "File2", "File3", "File4"]
for f in FilesToPack:
self.listWidget.addItem(f)
def PackFile(self):
#Put the files into a single ZIP file
PackedZipFileName = filedialog.asksaveasfile(mode='w', title="Save the HEC-RAS RasMapper ZIP file as...", filetypes=[("ZIP file","*.zip")], defaultextension=".zip")
zipObj = ZipFile(PackedZipFileName.name, mode='w')
for f in FilesToPack:
zipObj.write(f, f[len(RASpath):] if f.startswith(RASpath) else f) # eliminate long path prefix so files are packed in relative address form
zipObj.close()
def addItem(self,textitem):
self.listWidget.addItem(textitem)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
您可以将函数包装在由按下按钮调用的函数中:
伪代码:
@buttonclick():
do function A
populate list
do function B