📄 qdialogbuttonbox.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <QtCore/qhash.h>#include <QtGui/qpushbutton.h>#include <QtGui/qstyle.h>#include <QtGui/qlayout.h>#include <QtGui/private/qwidget_p.h>#include "qdialogbuttonbox.h"/*! \class QDialogButtonBox \since 4.2 \brief The QDialogButtonBox class is a widget that presents buttons in a layout that is appropriate to the current widget style. \ingroup application \mainclass Dialogs and message boxes typically present buttons in a layout that conforms to the interface guidelines for that platform. Invariably, different platforms have different layouts for their dialogs. QDialogButtonBox allows a developer to add buttons to it and will automatically use the appropriate layout for the user's desktop environment. Most buttons for a dialog follow certain roles. Such roles include: \list \o Accepting or rejecting the dialog. \o Asking for help. \o Performing actions on the dialog itself (such as resetting fields or applying changes). \endlist There can also be alternate ways of dismissing the dialog which may cause destructive results. Most dialogs have buttons that can almost be considered standard (e.g. \gui OK and \gui Cancel buttons). It is sometimes convenient to create these buttons in a standard way. There are a couple ways of using QDialogButtonBox. One ways is to create the buttons (or button texts) yourself and add them to the button box, specifying their role. \quotefromfile dialogs/extension/finddialog.cpp \skipto findButton \printuntil buttonBox->addButton(moreButton, QDialogButtonBox::ActionRole); Alternatively, QDialogButtonBox provides several standard buttons (e.g. OK, Cancel, Save) that you can use. They exist as flags so you can OR them together in the constructor. \quotefromfile dialogs/tabdialog/tabdialog.cpp \skipto buttonBox \printuntil connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); You can mix and match normal buttons and standard buttons. Currently the buttons are laid out in the following way if the button box is horizontal: \table 100% \row \o \inlineimage buttonbox-gnomelayout-horizontal.png GnomeLayout Horizontal \o Button box laid out in horizontal GnomeLayout \row \o \inlineimage buttonbox-kdelayout-horizontal.png KdeLayout Horizontal \o Button box laid out in horizontal KdeLayout \row \o \inlineimage buttonbox-maclayout-horizontal.png MacLayout Horizontal \o Button box laid out in horizontal MacLayout \row \o \inlineimage buttonbox-winlayout-horizontal.png WinLayout Horizontal \o Button box laid out in horizontal WinLayout \endtable The buttons are laid out the following way if the button box is vertical: \table 100% \row \o \inlineimage buttonbox-gnomelayout-vertical.png GnomeLayout Vertical \o Button box laid out in vertical GnomeLayout \row \o \inlineimage buttonbox-kdelayout-vertical.png KdeLayout Vertical \o Button box laid out in vertical KdeLayout \row \o \inlineimage buttonbox-maclayout-vertical.png MacLayout Vertical \o Button box laid out in vertical MacLayout \row \o \inlineimage buttonbox-winlayout-vertical.png WinLayout Vertical \o Button box laid out in vertical WinLayout \endtable Additionally, button boxes that contain only buttons with ActionRole or HelpRole can be considered modeless and have an alternate look on the mac: \table 100% \row \o \inlineimage buttonbox-mac-modeless-horizontal.png Screenshot of modeless horizontal MacLayout \o modeless horizontal MacLayout \row \o \inlineimage buttonbox-mac-modeless-vertical.png Screenshot of modeless vertical MacLayout \o modeless vertical MacLayout \endtable When a button is clicked in the button box, the clicked() signal is emitted for the actual button is that is pressed. For convenience, if the button has an AcceptRole, RejectRole, or HelpRole, the accepted(), rejected(), or helpRequested() signals are emitted respectively. If you want a specific button to be default you need to call QPushButton::setDefault() on it yourself. However, if there is no default button set and to preserve which button is the default button across platforms when using the QPushButton::autoDefault property, the first push button with the accept role is made the default button when the QDialogButtonBox is shown, \sa QMessageBox, QPushButton, QDialog*/enum { AcceptRole = QDialogButtonBox::AcceptRole, RejectRole = QDialogButtonBox::RejectRole, DestructiveRole = QDialogButtonBox::DestructiveRole, ActionRole = QDialogButtonBox::ActionRole, HelpRole = QDialogButtonBox::HelpRole, YesRole = QDialogButtonBox::YesRole, NoRole = QDialogButtonBox::NoRole, ApplyRole = QDialogButtonBox::ApplyRole, ResetRole = QDialogButtonBox::ResetRole, AlternateRole = 0x10000000, Stretch = 0x20000000, EOL = 0x40000000, Reverse = 0x80000000};static QDialogButtonBox::ButtonRole roleFor(QDialogButtonBox::StandardButton button){ switch (button) { case QDialogButtonBox::Ok: case QDialogButtonBox::Save: case QDialogButtonBox::Open: case QDialogButtonBox::SaveAll: case QDialogButtonBox::Abort: case QDialogButtonBox::Retry: return QDialogButtonBox::AcceptRole; case QDialogButtonBox::Cancel: case QDialogButtonBox::Close: case QDialogButtonBox::Ignore: return QDialogButtonBox::RejectRole; case QDialogButtonBox::Discard: return QDialogButtonBox::DestructiveRole; case QDialogButtonBox::Help: return QDialogButtonBox::HelpRole; case QDialogButtonBox::Apply: return QDialogButtonBox::ApplyRole; case QDialogButtonBox::Yes: case QDialogButtonBox::YesToAll: return QDialogButtonBox::YesRole; case QDialogButtonBox::No: case QDialogButtonBox::NoToAll: return QDialogButtonBox::NoRole; case QDialogButtonBox::RestoreDefaults: case QDialogButtonBox::Reset: return QDialogButtonBox::ResetRole; case QDialogButtonBox::NoButton: // NoButton means zero buttons, not "No" button ; } return QDialogButtonBox::InvalidRole;}static const int layouts[2][5][14] ={ // Qt::Horizontal { // WinLayout { ResetRole, Stretch, YesRole, AcceptRole, AlternateRole, DestructiveRole, NoRole, ActionRole, RejectRole, ApplyRole, HelpRole, EOL, EOL, EOL }, // MacLayout { HelpRole, ResetRole, ApplyRole, ActionRole, Stretch, DestructiveRole | Reverse, AlternateRole | Reverse, RejectRole | Reverse, AcceptRole | Reverse, NoRole | Reverse, YesRole | Reverse, EOL, EOL }, // KdeLayout { HelpRole, ResetRole, Stretch, YesRole, NoRole, ActionRole, AcceptRole, AlternateRole, ApplyRole, DestructiveRole, RejectRole, EOL }, // GnomeLayout { HelpRole, ResetRole, Stretch, ActionRole, ApplyRole | Reverse, DestructiveRole | Reverse, AlternateRole | Reverse, RejectRole | Reverse, AcceptRole | Reverse, NoRole | Reverse, YesRole | Reverse, EOL }, // Mac modeless { ResetRole, ApplyRole, ActionRole, Stretch, HelpRole, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL } }, // Qt::Vertical { // WinLayout { ActionRole, YesRole, AcceptRole, AlternateRole, DestructiveRole, NoRole, RejectRole, ApplyRole, ResetRole, HelpRole, Stretch, EOL, EOL, EOL }, // MacLayout { YesRole, NoRole, AcceptRole, RejectRole, AlternateRole, DestructiveRole, Stretch, ActionRole, ApplyRole, ResetRole, HelpRole, EOL, EOL }, // KdeLayout { AcceptRole, AlternateRole, ApplyRole, ActionRole, YesRole, NoRole, Stretch, ResetRole, DestructiveRole, RejectRole, HelpRole, EOL }, // GnomeLayout { YesRole, NoRole, AcceptRole, RejectRole, AlternateRole, DestructiveRole, ApplyRole, ActionRole, Stretch, ResetRole, HelpRole, EOL, EOL, EOL }, // Mac modeless { ActionRole, ApplyRole, ResetRole, Stretch, HelpRole, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL } }};class QDialogButtonBoxPrivate : public QWidgetPrivate{ Q_DECLARE_PUBLIC(QDialogButtonBox)public: QDialogButtonBoxPrivate(Qt::Orientation orient); QList<QAbstractButton *> buttonLists[QDialogButtonBox::NRoles]; QHash<QPushButton *, QDialogButtonBox::StandardButton> standardButtonHash; Qt::Orientation orientation; QDialogButtonBox::ButtonLayout layoutPolicy; QBoxLayout *buttonLayout; bool internalRemove; bool center; void createStandardButtons(QDialogButtonBox::StandardButtons buttons); void layoutButtons(); void initLayout(); void resetLayout(); QPushButton *createButton(QDialogButtonBox::StandardButton button, bool doLayout = true); void addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role, bool doLayout = true); void _q_handleButtonDestroyed(); void _q_handleButtonClicked(); void addButtonsToLayout(const QList<QAbstractButton *> &buttonList, bool reverse); void retranslateStrings(); const char *standardButtonText(QDialogButtonBox::StandardButton sbutton) const;};QDialogButtonBoxPrivate::QDialogButtonBoxPrivate(Qt::Orientation orient) : orientation(orient), buttonLayout(0), internalRemove(false), center(false){}void QDialogButtonBoxPrivate::initLayout(){ Q_Q(QDialogButtonBox); layoutPolicy = QDialogButtonBox::ButtonLayout(q->style()->styleHint(QStyle::SH_DialogButtonLayout, 0, q)); bool createNewLayout = buttonLayout == 0 || (orientation == Qt::Horizontal && qobject_cast<QVBoxLayout *>(buttonLayout) != 0) || (orientation == Qt::Vertical && qobject_cast<QHBoxLayout *>(buttonLayout) != 0); if (createNewLayout) { delete buttonLayout; if (orientation == Qt::Horizontal) buttonLayout = new QHBoxLayout(q); else buttonLayout = new QVBoxLayout(q); } int left, top, right, bottom; setLayoutItemMargins(QStyle::SE_PushButtonLayoutItem); getLayoutItemMargins(&left, &top, &right, &bottom); buttonLayout->setContentsMargins(-left, -top, -right, -bottom); if (!q->testAttribute(Qt::WA_WState_OwnSizePolicy)) { QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::ButtonBox); if (orientation == Qt::Vertical) sp.transpose(); q->setSizePolicy(sp); q->setAttribute(Qt::WA_WState_OwnSizePolicy, false); } // ### move to a real init() function q->setFocusPolicy(Qt::TabFocus);}void QDialogButtonBoxPrivate::resetLayout(){ //delete buttonLayout; initLayout(); layoutButtons();}void QDialogButtonBoxPrivate::addButtonsToLayout(const QList<QAbstractButton *> &buttonList, bool reverse){ int start = reverse ? buttonList.count() - 1 : 0; int end = reverse ? -1 : buttonList.count(); int step = reverse ? -1 : 1; for (int i = start; i != end; i += step) { QAbstractButton *button = buttonList.at(i); buttonLayout->addWidget(button); button->show(); }}void QDialogButtonBoxPrivate::layoutButtons(){ Q_Q(QDialogButtonBox); const int MacGap = 24 - 8; // 8 is the default gap between a widget and a spacer item for (int i = buttonLayout->count() - 1; i >= 0; --i) { QLayoutItem *item = buttonLayout->takeAt(i); if (QWidget *widget = item->widget()) widget->hide(); delete item; } int tmpPolicy = layoutPolicy; static const int M = 5; static int ModalRoles[M] = { AcceptRole, RejectRole, DestructiveRole, YesRole, NoRole }; if (tmpPolicy == QDialogButtonBox::MacLayout) { bool hasModalButton = false; for (int i = 0; i < M; ++i) { if (!buttonLists[ModalRoles[i]].isEmpty()) { hasModalButton = true; break; } } if (!hasModalButton) tmpPolicy = 4; // Mac modeless } const int *currentLayout = layouts[orientation == Qt::Vertical][tmpPolicy]; if (center)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -