PyQt开发(三):Events与Signals

  • A+
所属分类:Python


4月 23, 2018 1条评论
7,283次阅读
1人点赞

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()

点赞
分享
  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin