非主线程(GUI线程)中实现弹窗
目录
一、在非主线程(GUI线程)中实现弹窗
方法:在非主线程中发射槽信号,在主线程进行回应实现,
示例:使用PyQt5写多线程的界面时,在非主线程中实现在界面上弹窗(QMessageBox)
Step 1: 创建界面文件(ui_run_loop_dialog.py)
# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(640, 504)
self.gridLayoutWidget = QtWidgets.QWidget(Dialog)
self.gridLayoutWidget.setGeometry(QtCore.QRect(9, 19, 611, 471))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.pushButton = QtWidgets.QPushButton(self.gridLayoutWidget)
self.pushButton.setObjectName("pushButton")
self.gridLayout.addWidget(self.pushButton, 1, 1, 1, 1)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout.addItem(spacerItem, 1, 0, 1, 1)
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.label = QtWidgets.QLabel(self.gridLayoutWidget)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 2)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "非主线程(GUI线程)中实现弹窗"))
self.pushButton.setText(_translate("Dialog", "打开"))
self.label.setText(_translate("Dialog", "TextLabel"))
Step 2:代码主体 (run_loop_dialog.py)
import sys
from ui_run_loop_dialog import Ui_Dialog
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox
from PyQt5.QtCore import QThread, pyqtSignal, QTimer
from datetime import datetime
class MinWindow(QMainWindow, Ui_Dialog):
def __init__(self, parent=None):
super(MinWindow, self).__init__(parent)
self.setupUi(self)
self.time = QTimer()
self.time.setInterval(1000)
self.time.timeout.connect(self.refresh)
self.time.start()
self.message = Message(self)
self.message.signal.connect(self.box)
self.pushButton.clicked.connect(self.message.start)
def box(self):
QMessageBox.information(self, '提示', '成功!', QMessageBox.Ok)
def refresh(self):
now = datetime.now()
self.label.setText(str(now))
class Message(QThread):
signal = pyqtSignal()
def __init__(self, win):
super(Message, self).__init__()
self.window = win
def run(self):
self.signal.emit()
if __name__ == "__main__":
app = QApplication(sys.argv)
win = MinWindow()
win.show()
sys.exit(app.exec_())
其中:
(1)MinWindow为主线程,在MinWindow中实例化message线程,其中主线程中实例化一个Label实时显示时间。定义弹窗函数(box),QMessageBox.information作为示例。
(2)message为附加线程,message的运行由pushbutton控制。
(3)要利用meaasge实现在MinWindow中弹窗,则需要在message中定义信号:
signal = pyqtSignal()
并将这个信号与Window中的函数进行连接:
self.message.signal.connect(self.box)
则运行时将这个信号进行发射即可:
self.signal.emit()