pyside6 QThread 以及自定义信号 测试

import sys
import random
from time import sleep

from PySide6 import QtCore as qc
from PySide6 import QtWidgets as qw
# from PySide6 import QtGui as qg


class sub(qc.QThread):
    '''定义一个后台线程'''
    # 定义一个 信号, 信号要传递一个 bool 型参数
    sg = qc.Signal(bool)
    
    def __init__(self, *args, **kw):
        super().__init__(*args, **kw)
        
        # connect
        self.sg.connect(self.m1)
        
        # 自定一个信号,在后续,会触发这个信号。这个信号在别的线程
        self.sg2:qc.Signal = None    
        self._flg = False
        
    # 写一个 具体的过程
    def run(self): 
        try: 
            for _ in range(100):
                sleep(0.2)
                if self._flg:
                    if self.sg2 is not None:
                        # 在后台线程 发出信号, 发给相连接的前面线程
                        self.sg2.emit()                 
        except Exception as error:
            print(str(error))
            raise(error)

    # 接收信号,处理事务
    @qc.Slot(bool)
    def m1(self, v:bool): 
            self._flg = v
    

class MyWidget(qw.QWidget):
    
    def __init__(self):
        super().__init__()
        self.sgg:qc.Signal = None
        self.hello = ["Hallo A", "Hallo B", "Hallo C", "Hallo D"]
        self.v = True
        self.button = qw.QPushButton("Click me!")
        self.text = qw.QLabel("Hello World", alignment=qc.Qt.AlignCenter)
        self.b3 = qw.QPushButton("click to start")
        
        self.layout = qw.QVBoxLayout(self)
        self.layout.addWidget(self.text)
        self.layout.addWidget(self.button)
        self.layout.addWidget(self.b3)

        # qc.Qt.ConnectionType.QueuedConnection 在信号的接收方,延时执行动作
        qc.QObject.connect(self.button, qc.SIGNAL("clicked()"), self.magic, qc.Qt.ConnectionType.QueuedConnection)
        qc.QObject.connect(self.b3, qc.SIGNAL("clicked()"), self.m3, qc.Qt.ConnectionType.QueuedConnection)

    # 前台按扭的动作
    @qc.Slot()
    def magic(self):
        t = self.text.text()
        while True:
            s = random.choice(self.hello)
            if s != t:
                t = s
                break            
        self.text.setText(t)        

    # 前台按扭的动作,同时更新界面,并把信号发给后台
    @qc.Slot()
    def m3(self): 
        if self.sgg is not None:
            # 传一个 bool 值给后台
            self.sgg.emit(self.v)
            self.v = not self.v
            
        else:
            print('None')
        # 更新界面的文字
        self.b3.setText("click to start" if self.v else"click to stop")

    
if __name__ == "__main__":
    app = qw.QApplication([])
    widget = MyWidget()
    widget.resize(250, 150)
    # 创建后台线程
    p = sub()
    # 信号的传递
    widget.sgg = p.sg
    p.sg2 = widget.button.clicked
    widget.show()
    # 起动后台线程
    p.start()
    sys.exit(app.exec())

posted @ 2022-03-14 13:11  方头狮  阅读(777)  评论(0)    收藏  举报