У меня есть два окна.
Основное, которое выполняет некую функцию, используя при этом потоки. В определённый момент, основное окно вызывает побочное(окно уведомления). Если я не использую потоки, всё работает в норме, если использую. То окно уведомления появляется на короткий миг, в который оно не доступно, после чего исчезает(также возможно выставить 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()
Комментариев нет:
Отправить комментарий