Ricky Hao

PyQt开发(三):Events与Signals

0x00 前述

在写PyQt的时候,会发现由于UI线程是独立的,因此我们不能够在其他逻辑线程中,直接去对UI进行操作。而PyQt给我们提供了一个Signal系统,让我们能够在多线程中,对UI进行安全的交互。

0x01 关于Events

一个GUI程序,大部分是基于事件驱动的。比如一个Button,它会有一个clicked事件在它被点击的时候触发。因此,我们就可以将逻辑处理函数connect到这个事件。

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.loginButton.clicked.connect(self.loginFunction)

    def loginFunction(self):
        pass

对于菜单栏里的菜单来说,他们的点击事件可以用triggered

有时候,比如在一个ListWidget中,我们可能需要点击其中的一个item,并且需要获取这个item的数据。那么我们可以像下面这样,在触发事件的时候,传递我们触发的item

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ListWidget_1.itemClicked.connect(self.function)

    def function(self, item):
        print(item.text())

有时候,我们需要在UI事件被触发的时候,额外传输数据给处理函数,在这是我们可以使用functoolspartial来达到目的。

from functools import partial
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.Button_1.clicked.connect(partial(self.function, '123'))

    def function(self, data):
        print(data)

0x02 关于Signals

就像一开始所说,我们需要能够跨线程对UI进行更改,以及数据更新。这时候,我们就可以使用PyQt提供的Signal系统。
首先,我们需要创建一个pyqtSignal对象。(特别的,这个对象只能创建在类,而不能在实例里。并且,该类需要继承QtCore.Qobject

class SignalTest(QtCore.QObject):
    updateDataSignal = QtCore.pyqtSignal(str)
    clickedButtonSignal = QtCore.pyqtSignal()
    def __init__(self, parent=None):
        super().__init__(parent)

        self.updateDataSignal.connect(self.printData)
        self.clickedButtonSignal.connect(self.buttonClicked)

    def printData(self, data):
        print(data)

    def buttonClicked(self):
        print('Button clicked.')

对于需要数据传递的Signal来说,可以直接在定义Signal的时候确定这个参数的类型,最后调用的时候直接传参即可。
调用一个Signal对象的时候,我们需要使用.emit()方法。

def fun():
    test = SignalTest()
    test.updateDataSignal.emit('1234')
    test.clickedButtonSignal.emit()
点赞
  1. Silver说道:

    你看,所有GUI的机制终会导向某种Windows的设计思路(逃

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据