Consider this setup:
Main script, main.py
:
import sys
from PyQt5 import uic
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QApplication, QMainWindow
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.ui = uic.loadUi("mw.ui", self)
def on_btnFunc_clicked(self):
print('naked function call')
@pyqtSlot()
def on_btnSlot_clicked(self, bool):
print('slotted function call')
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
Qt Designer .ui form, mw.ui
:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>153</width>
<height>83</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="btnFunc">
<property name="text">
<string>naked func</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSlot">
<property name="text">
<string>slotted func</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>
This setup uses Qt's signal-slot autowire mechanic to bind button clicks to respective callbacks. Why does the naked callback get called twice while the slotted one only once as intended?
I found this and this but those setups are a bit different from mine, since I don't bind signals manually nor do I install an event filter.
I thought this behavior might occur due to signals with different signatures get bound to the same slot, but (if I understand correctly) QPushButton
has only one clicked()
signal.
Can someone, please, explain?