我已经将pyqt5与qt-designer一起使用了几周了。我习惯用connect语句将信号连接到处理函数。
昨天我编写了一段代码,该代码还自动将按钮单击的信号连接到没有pyqtSlot装饰器的处理程序函数。
将单击的信号连接到功能上时,单击一次按钮将导致该功能执行三次。
一次单击一次按钮,删除connect语句会使函数执行两次。
在函数中添加@pyqtSlot可以正常执行一次。
将处理程序函数重命名为“ on_ 按钮名称 _clicked”以外的其他名称也可以正常执行一次。
以下代码显示了这种“自动连接”行为。
谁能解释为什么在没有连接或pyqtSlot的情况下会发生这种带有双重处理程序的自动连接吗?
谢谢,梅斯
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QMainWindow
from PyQt5.uic import loadUi
import sys
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
loadUi('MainWindowTestButton.ui', self)
self.show()
def on_pushButton_clicked(self):
print('clicked')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MainWindow()
sys.exit(app.exec_())
上面的代码打印
点击
点击
单击一个按钮时。
这是示例中的MainWindowTestButton.ui文件
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindowTestButton</class>
<widget class="QMainWindow" name="MainWindowTestButton">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>70</x>
<y>60</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
答案 0 :(得分:3)
loadUi()
函数在内部调用connectSlotsByName()方法,如果某些方法具有以下结构,则会自动建立连接:
C ++:
void on_<object name>_<signal name>(<signal parameters>);
Python:
def on_<object name>_<signal name>(<signal parameters>):
在您的情况下,on_pushButton_clicked
方法满足该要求,因为您有一个QWidget
(从QObject继承)按钮,其对象名为"pushButton"
:
<widget class="QPushButton" name="pushButton">
具有称为clicked
的信号。
QPushButton包含一个单击的信号,该信号已重载,也就是说,存在多个具有相同名称但参数不同的信号。如果the docs被审核:
void QAbstractButton::clicked(bool checked = false)
虽然理解上面的代码可能会很复杂,但它等同于:
clicked = pyqtSignal([], [bool])
这类似于:
clicked = pyqtSignal()
clicked = pyqtSignal([bool])
因此,总而言之,QPushButton具有2个单击信号,这些信号将连接到on_pushButton_clicked函数,因此,当您按下按钮时,两个信号都将通过调用两种相同的方法而发出,从而将单击信号打印两次。
如果以前的信号是用相同的方法连接的,则不会考虑连接,因此,在您的手动连接中,将有3个连接(点击的信号中有2个不带参数[1个自动,另一个为手动]和1个带参数的)。信号点击带有参数),因此该方法将被调用3次。
在使用装饰器@pyqtSlot
时,您要指示签名(即参数的类型),因此connect方法将仅使用与插槽签名匹配的信号进行连接,因此看不到不再出现问题,因为您使用信号没有参数