Обработчик событий одной кнопки для кнопок

Я хотел бы создать приложение с графическим интерфейсом с некоторыми кнопками и хочу обрабатывать события нажатия кнопок таким же образом (т.е. обработчик одного события для всех нажатий клавиш). Но я не понимаю, как button_hanlder может понять, какая кнопка была нажата.

Вот код

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(800, 600)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.pushButton = QtGui.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(350, 190, 98, 27))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton_2 = QtGui.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(240, 220, 98, 27))
        self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
        self.pushButton_3 = QtGui.QPushButton(self.centralwidget)
        self.pushButton_3.setGeometry(QtCore.QRect(350, 250, 98, 27))
        self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))
        self.pushButton_4 = QtGui.QPushButton(self.centralwidget)
        self.pushButton_4.setGeometry(QtCore.QRect(460, 220, 98, 27))
        self.pushButton_4.setObjectName(_fromUtf8("pushButton_4"))
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 25))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        self.menuFile = QtGui.QMenu(self.menubar)
        self.menuFile.setObjectName(_fromUtf8("menuFile"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)
        self.menubar.addAction(self.menuFile.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QObject.connect(self.pushButton_2, QtCore.SIGNAL(_fromUtf8("pressed()")), self.button_handler)
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("pressed()")), self.button_handler)
        QtCore.QObject.connect(self.pushButton_4, QtCore.SIGNAL(_fromUtf8("pressed()")), self.button_handler)
        QtCore.QObject.connect(self.pushButton_3, QtCore.SIGNAL(_fromUtf8("pressed()")), self.button_handler)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton.setText(QtGui.QApplication.translate("MainWindow", "Up", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_2.setText(QtGui.QApplication.translate("MainWindow", "Right", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_3.setText(QtGui.QApplication.translate("MainWindow", "Down", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_4.setText(QtGui.QApplication.translate("MainWindow", "Left", None, QtGui.QApplication.UnicodeUTF8))
        self.menuFile.setTitle(QtGui.QApplication.translate("MainWindow", "File", None, QtGui.QApplication.UnicodeUTF8))

    def button_handler(self):
        # Which button was pressed?

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

Я хочу в button_handler определить, какая кнопка была нажата, например, по заголовку кнопки.


person Mikhail Boiko    schedule 21.11.2012    source источник


Ответы (2)


Для этого предназначена QButtonGroup. Он будет работать с любой кнопкой, которая наследует QAbstractButton, например, QPushButton, QRadioButton, QCheckBox и т. д.

Просто добавьте все кнопки в группу кнопок с помощью addButton и затем подключите сигнал buttonClicked к обработчику.

NB: может быть хорошей идеей поместить все кнопки внутри виджета-контейнера, такого как QGroupBox, QFrame или просто QWidget. Это позволит вам перебирать дочерние элементы контейнера и автоматически добавлять все кнопки в группу кнопок.

Пример кода:

btngroup.py:

from PyQt4 import QtGui, QtCore
from btngroup_ui import Ui_ButtonGroup

class Window(QtGui.QWidget, Ui_ButtonGroup):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.setupUi(self)
        self.buttonGroup = QtGui.QButtonGroup(self)
        for button in self.buttonBox.findChildren(QtGui.QAbstractButton):
            self.buttonGroup.addButton(button)
        self.buttonGroup.buttonClicked.connect(self.handleButtonClicked)

    def handleButtonClicked(self, button):
        print('"%s" was clicked' % button.text())

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

btngroup_ui.py:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'btngroup.ui'
#
# Created: Wed Nov 21 17:50:42 2012
#      by: PyQt4 UI code generator 4.9.5
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_ButtonGroup(object):
    def setupUi(self, ButtonGroup):
        ButtonGroup.setObjectName(_fromUtf8("ButtonGroup"))
        ButtonGroup.resize(240, 167)
        self.horizontalLayout = QtGui.QHBoxLayout(ButtonGroup)
        self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
        self.buttonBox = QtGui.QWidget(ButtonGroup)
        self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
        self.verticalLayout = QtGui.QVBoxLayout(self.buttonBox)
        self.verticalLayout.setMargin(0)
        self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
        self.buttonA = QtGui.QPushButton(self.buttonBox)
        self.buttonA.setObjectName(_fromUtf8("buttonA"))
        self.verticalLayout.addWidget(self.buttonA)
        self.buttonB = QtGui.QPushButton(self.buttonBox)
        self.buttonB.setObjectName(_fromUtf8("buttonB"))
        self.verticalLayout.addWidget(self.buttonB)
        self.buttonC = QtGui.QPushButton(self.buttonBox)
        self.buttonC.setObjectName(_fromUtf8("buttonC"))
        self.verticalLayout.addWidget(self.buttonC)
        self.buttonD = QtGui.QPushButton(self.buttonBox)
        self.buttonD.setObjectName(_fromUtf8("buttonD"))
        self.verticalLayout.addWidget(self.buttonD)
        self.horizontalLayout.addWidget(self.buttonBox)

        self.retranslateUi(ButtonGroup)
        QtCore.QMetaObject.connectSlotsByName(ButtonGroup)

    def retranslateUi(self, ButtonGroup):
        ButtonGroup.setWindowTitle(QtGui.QApplication.translate("ButtonGroup", "Button Group", None, QtGui.QApplication.UnicodeUTF8))
        self.buttonA.setText(QtGui.QApplication.translate("ButtonGroup", "Button A", None, QtGui.QApplication.UnicodeUTF8))
        self.buttonB.setText(QtGui.QApplication.translate("ButtonGroup", "Button B", None, QtGui.QApplication.UnicodeUTF8))
        self.buttonC.setText(QtGui.QApplication.translate("ButtonGroup", "Button C", None, QtGui.QApplication.UnicodeUTF8))
        self.buttonD.setText(QtGui.QApplication.translate("ButtonGroup", "Button D", None, QtGui.QApplication.UnicodeUTF8))
person ekhumoro    schedule 21.11.2012

Вероятно, вы захотите использовать QtCore.QSignalMapper.

См. http://srinikom.github.com/pyside-docs/PySide/QtCore/QSignalMapper.html для подробного объяснения.

По сути, он позволяет связать строковое значение с каждым соединением между кнопкой и слотом, чтобы можно было проверить, с какой кнопки происходит нажатие, анализируя содержимое строкового параметра сигнала.

person SirDarius    schedule 21.11.2012