假设了一个场景,在处理文件的时候遇到错误,弹出警告窗口,三个按钮分别为重试、忽略或取消,可是警告窗口未响应,没有显示内容
进度条窗口,附代码链接: https://gist.github.com/allrobot/3a6449b4389a1e28a907702d38d7422b
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import Script
from Vam_Dialogs import InterruptDialog
from Vam_Modules import ScanPackages
class ShowProgressBar(QWidget):
def __init__(self, MaxNumber: int,worker):
super().__init__()
self.worker=worker
# 忽略代码...
@pyqtSlot(str)
def show_dialog(self,text: str):
self.dialog = InterruptDialog.InterruptProcessing(text)
self.dialog.retry.connect(self.worker.resume)
self.dialog.ignored.connect(self.worker.ignore)
self.dialog.cancel.connect(progress_bar.progress_close)
self.dialog.cancel.connect(self.worker.quit)
'''输出依赖'''
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
app = QApplication(sys.argv)
worker = ScanPackages.Worker(r'I:\VAM\Vam Pure\AddonPackages')
progress_bar = ShowProgressBar(worker.exist_vars_path.__len__(),worker)
worker.intReady.connect(progress_bar.update_progress_bar)
worker.started.connect(worker.scan_meta_json)
worker.showdialog.connect(worker.pause)
worker.showdialog.connect(progress_bar.show_dialog)
worker.finished.connect(progress_bar.progress_close)
worker.start()
app.exec_()
QThread 代码,附代码链接: https://gist.github.com/allrobot/14be27794f8a9cd7dd08de40a3e443e9
def scan_meta_json(self) -> None:
num=0
for file in self.exist_vars_path:
self.intReady.emit(self.CurrentFiles)
num+=1
# 上锁
self.mutex.lock()
if num==500:
self.error = True
self.error_text = f'AddonPackages{file[1:]}\n\n 文件执行权限获取失败。\n\n 请确认文件是否被系统占用。\n\n 如果已关闭文件,点击返回继续处理操作任务。'
self.showdialog.emit(self.error_text)
if self.isPause:
self.condition.wait(self.mutex)
self.CurrentFiles += 1
print(file)
timer = QTimer()
timer.setSingleShot(True)
timer.start(1)
loop = QEventLoop()
timer.timeout.connect(loop.quit)
loop.exec()
self.mutex.unlock()
os.chdir(self.current_path)
self.finished.emit()
请问为啥未响应?对话框自测了,能正常打开,但进度条没法调用对话框显示内容。。。
对话框代码: https://gist.github.com/allrobot/aad2aa88f8ccdd8043a857478eebfab7
1
NoOneNoBody 2023-04-14 20:54:56 +08:00
太长,暂时没看完,先说三点
1. def close(self) : self.worker.quit() self.progress_close() def progress_close(self): self.close() 这两个互相调用?死循环? 2. worker.showdialog.connect(worker.pause) worker.showdialog.connect(progress_bar.show_dialog) connect 两个槽?把两个写到一块,connect 一个就好了 如果分属两个对象,用参数传递对象再调用就好了 3. 不要直接就 start 一个 Qthread 应该在窗口类里面写一个函数 A ,在 A 里面实例化一个 QThread ,及其相关的 connect ,start 实例化窗口的控件后,调用 A 或者在窗口 init 里面创建 QThread 对象 简单说应该在控件 show 后再调用 Qthread.start() 这样理,顺一些 感觉有点乱,例如等待用户响应的没必要用 timer ,timer 一般用在自动响应,如后台检查消息队列 这个批量处理的任务,不要中途弹出对话框比较好,有问题记入一个 log 或者变量,结束时一起作为消息汇总弹出 中途弹出要引入新的逻辑,如果弹出次数多每次还要点击操作,体验很差 |
2
NoOneNoBody 2023-04-14 21:11:58 +08:00
还有个大问题,你的 QThread 里面为何没有 run()? start 是自动执行这个的啊
把 scan_meta_json()改成 run()吧 worker.started.connect(worker.scan_meta_json) 这句就没必要了 另外 start 前最好加个判断 if not someThread.isRunning(): someThread.start() |
3
ALLROBOT OP @NoOneNoBody 感谢建议,我用口语化描述 qt 逻辑说给 GPT ,然后按 chatgpt 给的代码写出来的,但跑不出来,改一改就写成这样了。。。再问 GPT ,GPT 说的不知所云😂
对话框已解决,用 QMessageBox 即可,自己创建的对话框没法用 果然我还是应该看官网文档或书籍比较好一点,自己边看文档边写太费劲。。。 1. 代码写的欠缺逻辑 2. 真不知道有这用法,网上搜了下,可以写成:worker.showdialog[str].connect(lambda x:(worker.pause(),progress_bar.show_message_box(x))) 3. 受教了 |
4
kanchi240 2023-04-17 09:10:15 +08:00
不建议继承 QThread
|