Страницы

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

среда, 4 марта 2020 г.

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

#python #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_())

    


Ответы

Ответ 1



Пример с потоком, который выводит второе окно, как приходит сообщение из потока. При этом не блокируется ни основное окно, ни дополнительное. 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()

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

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