3

I wrote a minimal PyQt5 app which just shows a button and connects it's clicked signal to a method printing some string:

import sys
from PyQt5 import QtWidgets, uic

class HelloWindow(QtWidgets.QMainWindow):
    def __init__(self) -> None:
        super().__init__()
        uic.loadUi('hello.ui', self)

    def on_hello_button_clicked(self):
        print("Hello")

def main():
    app = QtWidgets.QApplication(sys.argv)
    window = HelloWindow()
    window.show()
    raise SystemExit(app.exec_())

if __name__ == "__main__":
    main()

Strangely on_hello_button_clicked - which gets autoconnected is being called twice when I press the button..

What's happening here?

This is hello.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>324</width>
    <height>87</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout">
    <item row="0" column="0">
     <widget class="QPushButton" name="hello_button">
      <property name="text">
       <string>PushButton</string>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

I'm using PyQt5 5.14 installed using pip, on Ubuntu.

frans
  • 8,868
  • 11
  • 58
  • 132

1 Answers1

3

You are using the connecting slots by name mechanic of PyQt5. The problem is, that there are two clicked signals in QAbstractButton. One is clicked() and the other is clicked(bool). Since overloading methods in python is not possible, both signals trigger your on_hello_button_clicked method.

You can avoid this by explicitly defining the on_hello_button_clicked method to receive the signals from clicked(), by adding the pyqtSlot decorator from PyQt5.QtCore, e.g.

from PyQt5.QtCore import pyqtSlot

class HelloWindow(QtWidgets.QMainWindow):
    # ...
    @pyqtSlot()
    def on_hello_button_clicked(self):
        print("Hello")
Erich
  • 1,838
  • 16
  • 20