Страницы

Поиск по вопросам

вторник, 21 мая 2019 г.

Создание нового окна в pyqt5, во время выполнения потока в основном окне

У меня есть два окна.
Основное, которое выполняет некую функцию, используя при этом потоки. В определённый момент, основное окно вызывает побочное(окно уведомления). Если я не использую потоки, всё работает в норме, если использую. То окно уведомления появляется на короткий миг, в который оно не доступно, после чего исчезает(также возможно выставить sleep, чтобы проверить это).
Вопрос: как организовать вызов второго окна, во время выполнения потоков в первом.
def thread(my_func): """ Run function in a different thread """ def wrapper(*args, **kwargs): my_thread = threading.Thread(target=my_func, args=args, kwargs=kwargs) my_thread.start() return wrapper
# Окно уведомлений class MsgBox(QWidget): def __init__(self): super(MsgBox, self).__init__()
self.setFixedSize(200, 50) self.location_on_the_screen() self.setWindowTitle('Сообщение')
self.lbl = QtWidgets.QLabel('', self) self.lbl.setOpenExternalLinks(True) self.lbl.move(15, 10) self.lbl.setText(self.message)
# Основное окно class Ui_Form(QMainWindow): # signal value for thread my_signal = QtCore.pyqtSignal(list, name='my_signal')
def setupUi(self, Form): # По клику выполняется метод func self.button.clicked.connect(lambda: self.func(self.my_signal))
# Обработчик сигнала self.my_signal.connect(self.mySignalHandler, QtCore.Qt.QueuedConnection)
# Метод создания окна уведомлений def create_window(self): second_window = MsgBox() second_window.show()
# Метод основной, выполняется с потоками @thread def func(self,my_signal): ....... self.create_window() ......
# Вызов if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv)
Form = QMainWindow() ui = Ui_Form() ui.get_from_config_file() ui.setupUi(Form) Form.show()
sys.exit(app.exec_())


Ответ

Пример с потоком, который выводит второе окно, как приходит сообщение из потока. При этом не блокируется ни основное окно, ни дополнительное.
from PyQt5 import Qt
class WorkThread(Qt.QThread): threadSignal = Qt.pyqtSignal(int)
def __init__(self): super().__init__()
def run(self, *args, **kwargs): c = 0 while True: Qt.QThread.msleep(1000) c += 1 self.threadSignal.emit(c) return Qt.QThread.run(self, *args, **kwargs)
class MsgBox(Qt.QDialog):
def __init__(self): super().__init__() layout = Qt.QVBoxLayout(self) self.label = Qt.QLabel("") layout.addWidget(self.label) close_btn = Qt.QPushButton("Close") close_btn.clicked.connect(self.close) layout.addWidget(close_btn) self.resize(50, 50)
class MainWindow(Qt.QMainWindow):
def __init__(self): super().__init__() self.resize(300, 200) self.btn = Qt.QPushButton("Run thread!") self.btn.clicked.connect(self.on_btn) self.msg = MsgBox() self.setCentralWidget(self.btn) self.thread = None
def on_btn(self): if self.thread is None: self.thread = WorkThread() self.thread.threadSignal.connect(self.on_threadSignal) self.thread.start() self.btn.setText("Stop thread") else: self.thread.terminate() self.thread = None self.btn.setText("Start thread")
def on_threadSignal(self, value): self.msg.label.setText(str(value)) if not self.msg.isVisible(): self.msg.show()
if __name__ == '__main__': app = Qt.QApplication([]) mw = MainWindow() mw.show() app.exec()

Комментариев нет:

Отправить комментарий