python - pyqt 按钮自动绑定到 on_..._clicked 函数,无需连接或 pyqtSlot
问题描述
我已经使用 pyqt5 和 qt-designer 几个星期了。我习惯于使用连接语句将信号连接到处理函数。
昨天我做了一段代码,它也自动将按钮单击信号连接到没有 pyqtSlot 装饰器的处理函数。
将 clicked 信号连接到函数会导致在单击按钮一次时执行该函数三次。
删除连接语句导致单击按钮一次时两次执行该功能。
将@pyqtSlot 添加到函数会导致正常的一次性执行。
将处理程序函数重命名为“on_ button-name _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>
解决方案
为什么要自动连接?
该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)带有 objectname 的 pushButton "pushButton"
:
<widget class="QPushButton" name="pushButton">
有一个信号叫clicked
.
为什么你两次调用相同的方法?
QPushButton 有一个被重载的 clicked 信号,也就是说有几个同名但参数不同的信号。如果审查了文档:
void QAbstractButton::clicked(bool checked = false)
虽然理解起来可能比较复杂,上面的代码相当于:
clicked = pyqtSignal([], [bool])
这类似于:
clicked = pyqtSignal()
clicked = pyqtSignal([bool])
所以总而言之 QPushButton 有 2 个 clicked 信号将连接到 on_pushButton_clicked 函数,所以当你按下按钮时,两个信号将通过调用相同的方法发出,这样 clicked 将被打印 2 次。
如果上一个信号是用相同的方法连接的,则连接不考虑,因此使用手动连接将有 3 个连接(其中 2 个信号在没有参数的情况下单击 [1 个自动,另一个手动],1 个信号被单击参数),因此该方法将被调用 3 次。
当您使用装饰器时@pyqtSlot
,您正在指示签名(即参数的类型),因此 connect 方法只会与与插槽签名匹配的信号建立连接,因此您不再看到问题,因为您使用了信号 no论据
推荐阅读
- amazon-ec2 - 端点 api 网关测试正常通过,但部署时出现错误 404
- mysql - 使用过的命令不允许再次使用
- javascript - 翻译后的div里面的Modal不占整个屏幕
- c# - unity,delegate 无法实现transform
- python - Python:如何从类中的函数调用特定变量?
- arrays - 如果 NSDecimalNumber 大于 Uint64,如何将 NSDecimalNumber 转换为字节数组?
- python - 列出所有 QtreeWidget 层次结构
- python - 为什么 pip 在它已经是最新的时候要求我升级?
- loops - Arduino中的游戏功能
- c# - 使用非托管可执行文件时设置 ServicePointManager.SecurityProcol 的正确方法