昨天在群里一个朋友提出了一个问题,要求在PyQt中click一个pushButton时给它的响应槽传入一个和发射信号的对象属性相关的参数,比如按顺序创建了N个pushButton,把这个次序数i告诉槽函数。
这本来看上去是一个很简单的问题,可问题就在于QPushButton只有click()等没有任何参数的信号,而自己在写相应的槽的时候无法让其再传入一个自定义的参数。而信号发射时如果不带参数的话槽函数根本无法获知是哪个widget向它发射了信号,自然也无法处理和发射对象相关的属性。
当然这个问题还得从qt的信号和槽机制说起,槽函数必须和信号的参数是保持一致的,定义信号发射时带了几个参数,槽函数被调用时就会以这几个参数为入参,这是关键的一步。我一直觉得qt自称最大特色的信号和槽机制是个不好的发明,也许它真的很强大,但它的机制很别扭,不容易理解,这会给开发者带来困惑,就像我一样。
于是就出了这样的问题,折腾了半天终于发现其实可以用事件响应来解决这个问题。Qt中的事件响应函数是widget对象的一个方法,也就是说任何从QWidget继承的类的对象都可以侦听到诸如mousePressEvent()之类的事件。这样一来,自定义一个从QPushButton继承的类,然后在其中重写mousePressEvent()方法,在该方法中emit()一个自定义的信号或者直接执行本来要由槽函数完成的动作即可。完整代码如下:
import sys
from PyQt4 import QtCore, QtGui
class ManyButton(QtGui.QDialog):
t = ['button1', 'button2', 'button3', 'button4', 'button5']
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.pb = []
vbox = QtGui.QVBoxLayout()
for i in range(len(self.t)):
self.pb.append(MyButton(self.t[i], self))
QtCore.QObject.connect(self.pb[i], QtCore.SIGNAL("myslot(str)"), self.myslot)
vbox.addWidget(self.pb[i])
self.setLayout(vbox)
self.resize(250, 150)
def myslot(self, text):
QtGui.QMessageBox.critical(self, "MessageShow", text, QtGui.QMessageBox.Ok)
class MyButton(QtGui.QPushButton):
def __init__(self, text, parent):
QtGui.QPushButton.__init__(self, text, parent)
def mouseReleaseEvent(self, event):
self.emit(QtCore.SIGNAL("myslot(str)"), self.text())
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mb = ManyButton()
mb.show()
sys.exit(app.exec_())
从中可以看出,其实我们通常关注并以为好像是一个函数的信号本身只是一个字符串,比如上面的myslot(str),你必须将这个字符串传入QtCore.SIGNAL()来生成信号。而信号定义的格式必须和emit时所带的参数个数一致,比如
self.emit(QtCore.SIGNAL("myslot(str, str)"), self.text1(), self.text2())
信号后面就必须跟上两个参数类型str,或者不写也行,但不能写成
self.emit(QtCore.SIGNAL("myslot(str)"), self.text1(), self.text2()), 这时会报错。
直接写成这样也是能正常运行的
self.emit(QtCore.SIGNAL("myslot"), self.text1(), self.text2())
也许信号和槽的机制在由多个发射源向多个槽发射信号时会起到很大作用,不过一般来讲,感觉这种机制还是太麻烦了一点。
分享到:
相关推荐
网上很多PyQt5信号槽与界面分离的例子,但是真正开发起来很不方便。 于是自己修改了。 1、真正实现PyQt5信号槽与界面分离,网上大部分分离不彻底; 2、不借助pycharm或anaconda软件,用python官网自带的安装程序+...
在pyqt5中,每一个QObject对象和pyqt中所有继承自QWidget的控件都支持信号和槽 当信号发射时,连接槽函数将会自动执行,pyqt5中信号与槽通过connect()函数连接起来的。 在pyqt5中信号主要分两类: 1.内置信号(详细参考...
Pyqt5信号与槽的简单应用,主要为自定义信号的介绍。类内部信号,类之间信号定义,信号的多态
PyQt Designer中连接信号和槽时为什么只能连接控件自己的信号和槽函数?.rar
在PyQt 5中信号与槽通过object.signal.connect()方法连接。 PyQt的窗口控件类中有很多内置信号,开发者也可以添加自定义信号。信号与槽具有如下特点。 一个信号可以连接多个槽。 一个信号可以连接另一个信号。 ...
多个按键的click信号映射到一个主窗口槽函数后,通过sender函数识别信号发送控件,再获取发送控件本身的文本作为显示和存储,最后计算输入表达式的值。 本文相关博文: PyQt学习随笔:槽函数获取信号发送对象的方法 ...
pyqt5 多窗口交互-使用信号与槽 两种方式,内置信号和自定义信号,供大家参考。
主要介绍了PyQt5通信机制 信号与槽详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
1.资源简介:PyQt5中使用多线程模块QThread解决了PyQt5界面程序执行比较耗时操作时,程序卡顿出现的无响应以及界面输出无法实时显示的问题,采用线程池ThreadPoolExecutor解决了ping多个IP多任务耗时问题。...
在下面这3篇文章中我们给出了手工输入代码的信号与槽的使用方法,因为采用这种方法介绍时,会简单一些,如果使用Qt Designer来介绍这些功能,那么任何一个简单的功能都会使用xxxx.ui xxxx.py call_xxxx.py三个文件 来...
Python3.x+Pyqt5实现主窗体与子窗体相互传数据、传字符、传值;主要使用了信号与槽的方法。
PyQt5中信号与槽可以说是对事件处理机制的高级封装,如果说事件是用来创建窗口控件的,那么信号与槽就是用来对这个控件进行使用的,比如一个按钮,当我们使用按钮时,只关心clicked信号,至于这个按钮如何接受并处里...
近期遇到界面中执行一些后台任务时界面卡死的情况,解决了在这里记录下。 PyQt PyQt简介 PyQt是Qt的python接口,PyQt的文档较少,但接口和函数可以完全参照Qt,继承了Qt中大量的控件以及信号机制,十分方便。以下...
PyQt5信号与槽高级自定义信号与槽 所谓高级自定义信号与槽,指的就是我们可以以自己喜欢的方式定义信号与槽函数,并传递参数,自定义信号的一般流程如下 定义信号 定义槽函数 连接信号与槽函数 发射信号 1、定义...
信号与槽有三种使用方法 第一种:内置信号与槽的使用 第二种:自定义信号与槽的使用 第三种:装饰器的信号与槽的使用 一: 内置信号与槽的使用 内置信号与槽的使用,是指在发射信号时,使用窗口控件的函数,而不是...
在PyQt5中QLineEdit里面的内容回车发送的方法是和PyQt4中不同的,主要是信号槽的写法的改变导致的。 具体不同如下: 在PyQt4中,我们要进行回车发送的时候,一般这么写: self.connect(self.lineEdit, SIGNAL...