Pyqt - 我的标准“应用”按钮会发出什么信号以及如何为其编写插槽?

问题描述 投票:0回答:3

我刚刚学习 pyqt,我正在尝试理解标准按钮。我刚刚学习,所以如果我做错了什么,请告诉我。

我在 QT Designer 中创建了一个带有一些标准按钮的简单 UI。

我注意到accepted()和rejected()信号被连接到accept和reject槽,所以我写了它们。 “确定”按钮和“取消”按钮按预期工作,但“应用”按钮根本没有反应。如何将应用按钮连接到插槽?

sample.py - 这是我的示例应用程序代码:

import sys
from PyQt4 import QtGui

import designer

class SampleApp(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self,parent)
        self.ui = designer.Ui_Dialog()
        self.ui.setupUi(self)

    def reject(w):
        print("reject", w)
        w.close()

    def accept(w):
        print("accept", w)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    myapp = SampleApp()
    myapp.show()
    sys.exit(app.exec_())

designer.py - 这是自动生成的 QT Designer 代码:

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

# Form implementation generated from reading ui file 'designer.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName(_fromUtf8("Dialog"))
        Dialog.resize(554, 399)
        self.buttonBox = QtGui.QDialogButtonBox(Dialog)
        self.buttonBox.setGeometry(QtCore.QRect(190, 340, 341, 32))
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Apply|QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.Ok)
        self.buttonBox.setCenterButtons(False)
        self.buttonBox.setObjectName(_fromUtf8("buttonBox"))

        self.retranslateUi(Dialog)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), Dialog.accept)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(_translate("Dialog", "Dialog", None))
python python-3.x pyqt signals-slots qdialog
3个回答
7
投票

您不需要为

accept()
reject()
编写插槽,因为
QDialog
类已经拥有它们。

当您创建一个新表单并选择“带有按钮的对话框”时,它将添加一个带有“确定”和“取消”按钮的按钮框,并且

accepted()/rejected()
信号将自动连接到对话框现有的
accept()
reject()
插槽.

但请注意,按钮和信号之间不存在一对一的关系。相反,有一组按钮角色,每个标准按钮都被分配了其中一个角色。所有带有

AcceptRole
的按钮都会发出
accepted()
信号,带有
RejectRole
的按钮将发出
rejected()
信号,而带有
HelpRole
的按钮将发出
helpRequested()
信号。但其他角色(例如
ApplyRole
)除了
clicked()
之外不会发出任何特定信号。

要处理这些其他按钮,您可以直接连接到每个按钮:

button = self.ui.buttonBox.button(QDialogButtonBox.Apply)
button.clicked.connect(self.handleApply)

或者像这样在一个槽中处理它们:

class SampleApp(QWidget):  
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = designer.Ui_Dialog()
        self.ui.setupUi(self)
        self.ui.buttonBox.clicked.connect(self.handleButtonClick)

    def handleButtonClick(self, button):
        role = self.buttonBox.buttonRole(button)
        if role == QDialogButtonBox.ApplyRole:
            print('Apply Clicked')
        elif role == QDialogButtonBox.ResetRole:
            print('Reset Clicked')        
        # and so on...

4
投票

您需要在小部件中手动连接来自

Apply
按钮的 clicked 信号。

class SampleApp(QtGui.QWidget):

    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self,parent)
        self.ui = designer.Ui_Dialog()
        self.ui.setupUi(self)
        btn = self.ui.buttonBox.button(QtGui.QDialogButtonBox.Apply)
        btn.clicked.connect(self.accept)

0
投票

您需要从

QDialogButtonBox
获取按钮并将
clicked
信号连接到所需的插槽。另外我建议您使用新型信号和插槽支持,这更直观:

您可以在下面定义要触发的插槽。您应该使用 @pyqtSlot() 装饰器来装饰它们。没有装饰器它也可以工作(文档页面中的更多信息)。

import sys
import designer

from PyQt4 import QtGui, QtCore


class SampleApp(QtGui.QWidget):

    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self,parent)
        self.ui = designer.Ui_Dialog()
        self.ui.setupUi(self)

    @QtCore.pyqtSlot()
    def reject(self):
        print("reject")
        self.close()

    @QtCore.pyqtSlot()
    def accept(self):
        print("accept")

    @QtCore.pyqtSlot()
    def apply(self):
        print("apply")


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    myapp = SampleApp()
    myapp.show()
    sys.exit(app.exec_())

在下面,您可以将按钮的

clicked
操作连接到您在此处定义的插槽。请注意,对于
Close
Ok
来说,这并不是真正必要的,因为当使用标准按钮时,如果程序员未指定,PyQt 会自动将它们连接到默认操作。虽然我手动连接了它们,所以您可以了解发生了什么。

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

# Form implementation generated from reading ui file 'designer.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_Dialog(object):

    def setupUi(self, Dialog):
        Dialog.setObjectName(_fromUtf8("Dialog"))
        Dialog.resize(554, 399)
        self.buttonBox = QtGui.QDialogButtonBox(Dialog)
        self.buttonBox.setGeometry(QtCore.QRect(190, 340, 341, 32))
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Apply|QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.Ok)
        self.buttonBox.setCenterButtons(False)
        self.buttonBox.setObjectName(_fromUtf8("buttonBox"))

        self.retranslateUi(Dialog)

        self.buttonBox.button(QtGui.QDialogButtonBox.Close).clicked.connect(Dialog.reject)
        self.buttonBox.button(QtGui.QDialogButtonBox.Ok).clicked.connect(Dialog.accept)
        self.buttonBox.button(QtGui.QDialogButtonBox.Apply).clicked.connect(Dialog.apply)

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(_translate("Dialog", "Dialog", None))
© www.soinside.com 2019 - 2024. All rights reserved.