У меня есть приложение командной строки, которое выполняет длинную задачу.В настоящее время я пытаюсь добавить к нему пользовательский интерфейс и использую Qt.Приложение должно время от времени уведомлять пользователя через два диалоговых окна, и что бы я ни пытался, я не могу заставить его работать.
Итак, я делаю следующее: сначала я создаю QApplication
, затем создаюодиночный снимок QTimer
, который затем выполняет долгосрочную задачу, а затем я запускаю exec()
метод приложения.Внутри длительной задачи я пытаюсь вызвать методы диалоговых окон show()
и hide()
, но окна не отображаются должным образом и просто отображаются черным (по крайней мере, в Ubuntu 18.04).
Если я вызываю exec()
метод диалогового окна из длительной задачи, диалог отображается правильно, но это, конечно, блокирует задачу, пока окно не будет закрыто.
Есть ли способ сделатьэто работает, не блокируя долго выполняющуюся задачу?
См. код ниже для минимального нерабочего примера:
#!/usr/bin/env python3
import sys
import time
from PyQt5 import QtCore, QtWidgets
class Dialog(QtWidgets.QDialog):
"""Dialog window with just a text label."""
def __init__(self, text, parent=None):
self.text = text
super().__init__(parent)
self.setupUi()
def setupUi(self):
self.layout = QtWidgets.QVBoxLayout()
self.label = QtWidgets.QLabel(self.text)
self.setLayout(self.layout)
self.layout.addWidget(self.label)
class Application(QtWidgets.QApplication):
"""An example QApplication launching the worker function."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.root = Dialog("Root window")
self.dialog_a = Dialog("Dialog A")
self.dialog_b = Dialog("Dialog B")
def show_a(self):
self.dialog_b.hide()
self.dialog_a.show()
def show_b(self):
self.dialog_a.hide()
self.dialog_b.show()
def exec(self):
QtCore.QTimer.singleShot(0, lambda: worker(self))
super().exec()
def worker(app):
"""
This is the main worker function that should occasionaly ask
Application to show different dialog windows. Unfortunately the
windows do not get rendered until the worker function is done.
"""
app.show_a()
for _ in range(10):
time.sleep(0.5)
print(".")
app.show_b()
for _ in range(10):
time.sleep(0.5)
print(".")
app = Application([])
app.exec()