pyqt信号和槽传递额外参数

环境:

python2.7.8

pyqt 4.11.1


使用Pyqt编程过程中,经常会遇到给槽函数传递额外参数的情况。但是信号-槽机制只是指定信号如何连接到槽,信号定义的参数被传递给槽,而额外的参数(用户定义)不能直接传递。

而传递额外参数又是很有用处。你可能使用一个槽处理多个组件的信号,有时要传递额外的信息。


一种方法是使用lambda表达式。

from PyQt4.QtCore import *
from PyQt4.QtGui import *

class MyForm(QMainWindow):
    def __init__(self, parent=None):
        super(MyForm, self).__init__(parent)
        button1 = QPushButton('Button 1')
        button2 = QPushButton('Button 1')
        button1.clicked.connect(lambda: self.on_button(1))
        button2.clicked.connect(lambda: self.on_button(2))

        layout = QHBoxLayout()
        layout.addWidget(button1)
        layout.addWidget(button2)

        main_frame = QWidget()
        main_frame.setLayout(layout)

        self.setCentralWidget(main_frame)

    def on_button(self, n):
        print('Button {0} clicked'.format(n))

if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    form = MyForm()
    form.show()
    app.exec_()



解释一下,on_button是怎样处理从两个按钮传来的信号。我们使用lambda传递按钮数字给槽,也可以传递任何其他东西---甚至是按钮组件本身(假如,槽打算把传递信号的按钮修改为不可用)


第2个方法是使用functools里的partial函数。

button1.clicked.connect(partial(self.on_button, 1))
button2.clicked.connect(partial(self.on_button, 2))


哪个办法好一点?这个属于风格的问题。个人观点,喜欢lambda,条理清楚,而且灵活。


《Rapid GUI Program with Python and QT》 P143例子。



from PyQt4.QtCore import *
from PyQt4.QtGui import *
from functools import partial
import sys

class Bu1(QWidget):
  
    def __init__(self, parent=None):
        super(Bu1, self).__init__(parent)
        #水平盒式布局
        layout = QHBoxLayout()
        #显示
        self.lbl = QLabel('no button is pressed')
        #循环5个按钮
        for i in range(5):
            but = QPushButton(str(i))
            layout.addWidget(but)
            #信号和槽连接
            but.clicked.connect(self.cliked)
            
        #使用封装,lambda
        but = QPushButton('5')
        layout.addWidget(but)
        but.clicked.connect(lambda: self.on_click('5'))
        #使用个who变量,结果不正常,显示 False is pressed
        #but.clicked.connect(lambda who="5": self.on_click(who))
        
        #使用封装,partial函数
        but = QPushButton('6')
        layout.addWidget(but)
        but.clicked.connect(partial(self.on_click, '6'))
        
        layout.addWidget(self.lbl)
        #设置布局
        self.setLayout(layout)
        
    #传递额外参数   
    def cliked(self):
        bu = self.sender()
        if isinstance(bu, QPushButton):
            self.lbl.setText('%s is pressed' % bu.text())
        else:
            self.lbl.setText('no effect')
    def on_click(self, n):
        self.lbl.setText('%s is pressed' % n)
            
if __name__ == '__main__':        
    app = QApplication(sys.argv)
    bu =Bu1()
    bu.show()
    app.exec_()


  • 13
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
PyQt5中,信号是用于对象间通信的机制。当一个对象的状态发生改变时,它会发出一个信号,其他对象可以通过连接该信号来接收该信号并做出响应。是一个函数,当一个信号被发出时,它会被调用执行。 在信号的连接过程中,可以传递参数。当信号发出时,它可以附带一些数据,这些数据可以在函数中进行处理。传递参数的方式有多种,以下是其中的两种方式: 1. 使用lambda表达式: ```python import sys from PyQt5.QtCore import pyqtSignal, QObject from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton class Signal(QObject): signal = pyqtSignal(int) class Slot(QObject): def __init__(self): super().__init__() def handle(self, num): print('slot received:', num) if __name__ == '__main__': app = QApplication(sys.argv) signal = Signal() slot = Slot() signal.signal.connect(lambda num: slot.handle(num)) signal.signal.emit(1) sys.exit(app.exec_()) ``` 2. 使用functools.partial: ```python import sys from functools import partial from PyQt5.QtCore import pyqtSignal, QObject from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton class Signal(QObject): signal = pyqtSignal(int) class Slot(QObject): def __init__(self): super().__init__() def handle(self, num, text): print('slot received:', num, text) if __name__ == '__main__': app = QApplication(sys.argv) signal = Signal() slot = Slot() signal.signal.connect(partial(slot.handle, text='hello')) signal.signal.emit(1) sys.exit(app.exec_()) ``` 以上两种方式都可以在函数中接收到附带的参数。如果你还有其他相关问题,请随时问我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值