pyqt按钮自动绑定到on_ ... _clicked函数,没有connect或pyqtSlot

问题描述 投票:1回答:1

几周以来,我一直在使用pyqt5和qt-designer。我习惯用connect语句将信号连接到处理函数。

昨天我制作了一段代码,它也自动将按钮点击信号连接到处理函数而没有pyqtSlot装饰器。

  • 将单击的信号连接到某个功能导致在单击按钮一次时执行该功能三次。
  • 删除connect语句导致在单击按钮一次时执行该函数两次。
  • 将@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>
python pyqt pyqt5 qt-designer
1个回答
3
投票

Why this auto connect?

loadUi()函数在内部调用connectSlotsByName()方法,如果某个方法具有以下结构,则该方法会自动连接:

C ++:

void on_<object name>_<signal name>(<signal parameters>);

蟒蛇:

def on_<object name>_<signal name>(<signal parameters>):

在你的情况下,on_pushButton_clicked方法符合该要求,因为你有一个QWidget(继承自QObject)pushButton与objectname "pushButton"

<widget class="QPushButton" name="pushButton">

有一个叫做clicked的信号。

Why do you call the same method twice?

QPushButton有一个重载的点击信号,也就是说有几个具有相同名称但具有不同参数的信号。如果the docs被审查:

void QAbstractButton::clicked(bool checked = false)

虽然理解上述代码可能很复杂,但相当于:

clicked = pyqtSignal([], [bool])

这类似于:

clicked = pyqtSignal()
clicked = pyqtSignal([bool])

因此总之,QPushButton有2个点击信号将连接到on_pushButton_clicked函数,所以当你按下按钮时,两个信号将通过调用相同的方法发出,以便点击将被打印2次。


连接不考虑先前的信号是否使用相同的方法连接,因此在手动连接时将有3个连接(信号中的2个没有参数[1自动和另一个手动]点击1和1点击信号参数)所以该方法将被调用3次。

当您使用装饰器@pyqtSlot时,您指示签名(即参数的类型),因此connect方法将仅与与插槽签名匹配的信号建立连接,因此您不再看到问题,因为您使用了信号没有争论

© www.soinside.com 2019 - 2024. All rights reserved.