将作业从线程委派给PyQt5中的主线程以停止GUI冻结

时间:2019-12-09 13:27:33

标签: python multithreading pyqt5

我有一个GUI,我想使某些按钮闪烁。我无法使其与QPropertyAnimation一起使用,但是我发现了一种或多或少有效的解决方法。我要做的是,为按钮创建背景颜色“层”,并在与主线程分开的线程中在它们之间切换,以便仍处理与GUI的交互。

问题是GUI随机冻结,我无法重现导致冻结的确切原因。单击按钮后,GUI会立即冻结,然后再次运行一段时间,直到再次冻结。

我想解决的问题是,如果我让负责闪烁的线程将实际的闪烁委托给运行GUI的主线程。如何在python中实现呢? 下面是一个小示例(运行它时,它也会对我随机冻结,并在单击按钮时解冻):

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
import time
import threading

class App(QWidget):

    def __init__(self):
        super().__init__()
        self.left = 10
        self.top = 10
        self.width = 320
        self.height = 200
        self.initUI()

    def initUI(self):
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.button = QPushButton('PyQt5 button', self)
        self.button.setToolTip('This is an example button')
        self.button.move(100, 70)
        self.button.clicked.connect(self.on_click)

        self.show()

        self.t_blink = threading.Thread(target=self.blink_button)
        self.t_blink.start()

    def on_click(self):
        print('PyQt5 button click')

    def blink_button(self):
        self.toplayer_color = 'background-color:rgba(255, 255, 255, 90)'
        self.bottomlayer_color = 'background-color:rgba(255, 255, 255, 0)'

        while True:
            self.button.setStyleSheet(self.toplayer_color)
            time.sleep(1)
            self.button.setStyleSheet(self.bottomlayer_color)
            time.sleep(1)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

我想做什么:

    def blink_button(self):
        self.toplayer_color = 'background-color:rgba(255, 255, 255, 90)'
        self.bottomlayer_color = 'background-color:rgba(255, 255, 255, 0)'

        while True:
            # do this in Main Thread
            self.button.setStyleSheet(self.toplayer_color)
            # do this in blinking thread to not block MainThread
            time.sleep(1)
            # do this in Main Thread
            self.button.setStyleSheet(self.bottomlayer_color)
            # do this in blinking thread to not block MainThread
            time.sleep(1)

谢谢

0 个答案:

没有答案