You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5技术问题:如何识别被点击的QPushButton

解决PyQt5中识别点击按钮的问题

你已经找对了问题的核心:sender() 是QObject类的方法,而Qt Designer生成的Ui_MainWindow类继承自object而非QObject子类,所以直接在这个类的槽函数里调用sender()会失效。下面给你两种实用的解决方案,按需选择即可:

方案1:将槽函数移到主窗口类(推荐)

Qt Designer生成的UI类最好只负责界面元素的初始化,把业务逻辑(比如按钮点击处理)放到继承自QMainWindow的主类中——这类主类本身就是QObject的子类,能正常调用sender()。

示例代码:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        
        # 创建按钮1
        self.btn1 = QtWidgets.QPushButton(self.centralwidget)
        self.btn1.setGeometry(QtCore.QRect(100, 100, 100, 30))
        self.btn1.setObjectName("btn1")
        self.btn1.setText("按钮1")
        
        # 创建按钮2
        self.btn2 = QtWidgets.QPushButton(self.centralwidget)
        self.btn2.setGeometry(QtCore.QRect(100, 150, 100, 30))
        self.btn2.setObjectName("btn2")
        self.btn2.setText("按钮2")
        
        MainWindow.setCentralWidget(self.centralwidget)

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        # 连接按钮信号到主类的槽函数
        self.ui.btn1.clicked.connect(self.btnListener)
        self.ui.btn2.clicked.connect(self.btnListener)
    
    def btnListener(self):
        # 这里可以正常调用sender()获取点击的按钮
        clicked_btn = self.sender()
        if clicked_btn == self.ui.btn1:
            print("按钮1被点击了")
        elif clicked_btn == self.ui.btn2:
            print("按钮2被点击了")
        # 也可以通过objectName判断
        elif clicked_btn.objectName() == "btn1":
            # 另一种判断逻辑
            pass

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

方案2:用Lambda表达式传递按钮标识

如果不想调整类结构,也可以在连接信号时直接把按钮的信息(对象/名称)通过lambda传递给槽函数,完全不需要依赖sender()。

修改你的原代码示例:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.widget = QtWidgets.QWidget(MainWindow)
        self.widget.setObjectName("widget")
        
        self.btn1 = QtWidgets.QPushButton(self.widget)
        self.btn1.setGeometry(QtCore.QRect(100, 100, 100, 30))
        self.btn1.setObjectName("btn1")
        self.btn1.setText("按钮1")
        # 连接时用lambda传递按钮对象
        self.btn1.clicked.connect(lambda: self.btnListener(self.btn1))
        
        self.btn2 = QtWidgets.QPushButton(self.widget)
        self.btn2.setGeometry(QtCore.QRect(100, 150, 100, 30))
        self.btn2.setObjectName("btn2")
        self.btn2.setText("按钮2")
        self.btn2.clicked.connect(lambda: self.btnListener(self.btn2))
        
        MainWindow.setCentralWidget(self.widget)
    
    def btnListener(self, btn):
        # 直接通过参数拿到点击的按钮
        if btn.objectName() == "btn1":
            print("按钮1被点击")
        elif btn == self.btn2:
            print("按钮2被点击")

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

小提示

  • 方案1更符合PyQt的开发规范,将UI和业务逻辑分离,后续维护更方便。
  • 如果是动态生成按钮(比如循环创建),用lambda传参时要注意变量捕获问题,需要用默认参数规避:lambda btn=current_btn: self.btnListener(btn)

内容的提问来源于stack exchange,提问作者Enzy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:10:50