Search code examples
pythonpyqt5signals-slotsslot

PyQt5 call slot for two times


import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QFileDialog
from PyQt5.QtCore import QCoreApplication
from PyQt5 import uic

qt_design_ui = "/home/lin/program/Qt/Notepad/notepad.ui"
Ui_Notepad, QtBaseClass = uic.loadUiType(qt_design_ui)

class Notepad(QMainWindow, Ui_Notepad):
    def __init__(self):
        super(Notepad, self).__init__()
        self.setupUi(self)
    def on_quitButton_clicked(self):
        # QCoreApplication.quit();
        print("h")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Notepad()
    window.show()
    sys.exit(app.exec_())

UI file generated by QtDesign:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Notepad</class>
 <widget class="QMainWindow" name="Notepad">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Notepad</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <widget class="QWidget" name="layoutWidget">
    <property name="geometry">
     <rect>
      <x>70</x>
      <y>10</y>
      <width>258</width>
      <height>222</height>
     </rect>
    </property>
    <layout class="QVBoxLayout" name="verticalLayout">
     <item>
      <widget class="QPushButton" name="quitButton">
       <property name="layoutDirection">
        <enum>Qt::LeftToRight</enum>
       </property>
       <property name="text">
        <string>Quit</string>
       </property>
      </widget>
     </item>
    </layout>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>400</width>
     <height>19</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
  <action name="actionOpen">
   <property name="text">
    <string>Open</string>
   </property>
  </action>
  <action name="actionSave">
   <property name="text">
    <string>Save</string>
   </property>
  </action>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

When the button is clicked, an 'h' is supposed to be output.

However, two 'h's are output acturally.

Maybe the connection is bind for two times somewhere. But I don't where it happens.

And, if I add self.quitButton.clicked.connect(self.on_quitButton_clicked) into __init__, 3 'h's are output.

When writing in C++, it's OK.

Version of Python3:

Python 3.5.2

Version of PyQt5:

Name: PyQt5
Version: 5.9
Summary: Python bindings for the Qt cross platform UI and application toolkit
Home-page: https://www.riverbankcomputing.com/software/pyqt/
Author: Riverbank Computing Limited
Author-email: [email protected]
License: GPL v3
Location: /usr/local/lib/python3.5/dist-packages
Requires: sip

Solution

  • This problem happens because you are using the Connecting Slots By Name feature. If a signal has multiple overloads, an automatic connection will be made for each one of them. The clicked signal has two overloads: one that sends a default checked parameter, and one that doesn't. To select only one of these, you need to define the slot like this:

    class Notepad(QMainWindow, Ui_Notepad):
        ...
        @QtCore.pyqtSlot()
        def on_quitButton_clicked(self):
            print("hello world")