![](/img/trans.png)
[英]Django: Why are my static files not showing up and always giving me a 404 error when DEBUG=False?
[英]Why is QProgressDialog always showing at app startup?
在 PyQt GUI 中,我將有幾個工作人員(與 QThread 關聯的 QObject),每個工作人員有 1 個 QProgressDialog。 每個人的壽命可能與另一個不同。
我天真地做了下面的例子,我在 GUI初始化時創建了所有必要的 QProgressDialog。
然而,每個在初始化時定義的 QProgressDialog 都會在啟動時顯示,即使我明確地將可見性設置為 False。 我多次嘗試使用 QProgressDialog,似乎工作版本都是基於每次我們需要它時創建的新QProgressDialog 實例。
為什么 QProgressDialog 在啟動時顯示? 即時實例化是否更可取? (我不是在尋找意見,而是來自 Qt 代碼或 Qt 文檔的正式元素我可能錯過了)
處理進度對話框/進度條管理有各種問題,但似乎都沒有解決我的問題。 PyQt QProgressDialog 文檔對此沒有任何解釋, QDialog 文檔也沒有。
MCVE:
import sys
import time
from PyQt5.QtCore import QThread, Qt, QObject, pyqtSignal
from PyQt5.QtWidgets import (QApplication, QMainWindow, QProgressDialog, QPushButton)
class WorkerA(QObject):
finished = pyqtSignal()
def do_it(self):
time.sleep(5)
self.finished.emit()
class Window(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setMinimumSize(250, 250)
self.button = QPushButton(self)
self.button.setText("Start worker A")
self.button.clicked.connect(self.start_worker_A)
self.thread_A = QThread()
self.thread_A.setObjectName("ThreadA")
self.worker_A = WorkerA()
self.progress_dialog_A = QProgressDialog("Work A in progress", None, 0, 0, self)
self.progress_dialog_A.setWindowModality(Qt.ApplicationModal)
self.progress_dialog_A.setCancelButton(None)
self.progress_dialog_A.setWindowTitle("Work A")
self.progress_dialog_A.setVisible(False)
self.progress_dialog_A.hide()
self.thread_B = QThread()
self.thread_B.setObjectName("ThreadB")
self.worker_B = None
self.progress_dialog_B = QProgressDialog("Work B in progress", None, 0, 0, self)
self.progress_dialog_B.setWindowModality(Qt.ApplicationModal)
self.progress_dialog_B.setCancelButton(None)
self.progress_dialog_B.setWindowTitle("Work B")
self.progress_dialog_B.setVisible(False)
self.progress_dialog_B.hide()
def start_worker_A(self):
if not self.thread_A.isRunning():
self.button.setEnabled(False)
self.worker_A.moveToThread(self.thread_A)
self.thread_A.started.connect(self.worker_A.do_it)
self.thread_A.started.connect(self.progress_dialog_A.show)
self.worker_A.finished.connect(self.thread_A.quit)
self.worker_A.finished.connect(self.progress_dialog_A.hide)
self.worker_A.finished.connect(self.enable_button)
self.thread_A.start()
else:
pass
def enable_button(self):
self.button.setEnabled(True)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec())
上面的代碼總是在應用程序啟動時顯示 QProgressDialog,即使它們的可見性從未被顯式調用。
我嘗試了以下變體,效果很好,但我不明白 QProgressDialog 的生命周期邏輯。
class Window(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setMinimumSize(250, 250)
self.button = QPushButton(self)
self.button.setText("Start worker A")
self.button.clicked.connect(self.start_worker_A)
self.thread_A = QThread()
self.thread_A.setObjectName("ThreadA")
self.worker_A = WorkerA()
self.progress_dialog_A : QProgressDialog = None
# obviously no further operations here on self.progress_dialog_A
# rest of init as first code sample above
def start_worker_A(self):
if not self.thread_A.isRunning():
self.button.setEnabled(False)
# QProgressDialog instantiated only when needed
# any previous reference to QProgressDialog is garbaged collected ?
# and a new instance created on the fly
self.progress_dialog_A = QProgressDialog("Work A in progress", None, 0, 0, self)
self.progress_dialog_A.setWindowModality(Qt.ApplicationModal)
self.progress_dialog_A.setCancelButton(None)
self.progress_dialog_A.setWindowTitle("Work A")
self.progress_dialog_A.setVisible(False)
self.progress_dialog_A.hide()
self.worker_A.moveToThread(self.thread_A)
self.thread_A.started.connect(self.worker_A.do_it)
self.thread_A.started.connect(self.progress_dialog_A.show)
self.worker_A.finished.connect(self.thread_A.quit)
self.worker_A.finished.connect(self.progress_dialog_A.hide)
self.worker_A.finished.connect(self.enable_button)
self.thread_A.start()
else:
pass
# rest of code unchanged
我還嘗試覆蓋默認的 window show() 但沒有成功:
def show(self):
super(Window, self).show()
self.progress_dialog_A.hide()
self.progress_dialog_B.hide()
這是預期的行為,雖然一開始可能不是很清楚,但在文檔中對此進行了解釋。
從詳細描述:
它估計操作將花費的時間(基於步驟的時間),並且僅在該估計超出 minimumDuration() 時顯示自身
然后, minimumDuration()
:
此屬性保存對話框出現之前必須經過的時間。
如果任務的預期持續時間小於 minimumDuration,則對話框根本不會出現。 這可以防止為快速結束的任務彈出對話框。 對於預期超過 minimumDuration 的任務,對話框將在 minimumDuration 時間后或設置任何進度后立即彈出。
如果設置為 0,則在設置任何進度后始終顯示對話框。 默認值為 4000 毫秒。
這是通過內部 QTimer 實現的,該 QTimer 在給定的minimumDuration()
(默認為 4 秒)超時后立即調用forceShow()
)。
一種可能的解決方案是在創建對話實例后立即停止計時器:
self.progress_dialog_A.findChild(QTimer).stop()
self.progress_dialog_B.findChild(QTimer).stop()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.