1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the widgets module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "qapplication.h"
31
#include "qdesktopwidget.h"
33
#include <private/qdialog_p.h>
34
#include "qdrawutil.h"
36
#include "qfontmetrics.h"
38
#include "qstylepainter.h"
41
#include "qpushbutton.h"
43
#include "qstyleoption.h"
46
#ifndef QT_NO_ACCESSIBILITY
47
#include "qaccessible.h"
50
#include "private/qabstractbutton_p.h"
53
class QPushButtonPrivate : public QAbstractButtonPrivate
55
Q_DECLARE_PUBLIC(QPushButton)
57
QPushButtonPrivate():autoDefault(true), defaultButton(false), flat(false){}
60
QStyleOptionButton getStyleOption() const;
63
uint defaultButton : 1;
68
\class QPushButton qpushbutton.h
69
\brief The QPushButton widget provides a command button.
74
The push button, or command button, is perhaps the most commonly
75
used widget in any graphical user interface. Push (click) a button
76
to command the computer to perform some action, or to answer a
77
question. Typical buttons are OK, Apply, Cancel, Close, Yes, No
80
A command button is rectangular and typically displays a text
81
label describing its action. An underlined character in the label
82
(signified by preceding it with an ampersand in the text)
83
indicates a shortcut key, e.g.
85
QPushButton *pb = new QPushButton("&Download", this);
87
In this example the shortcut is \e{Alt+D}, and the label text
88
will be displayed as \bold{\underline{D}ownload}.
90
Push buttons display a textual label, and optionally a small
91
icon. These can be set using the constructors and changed later
92
using setText() and setIcon(). If the button is disabled the
93
appearance of the text and icon will be manipulated with respect
94
to the GUI style to make the button look "disabled".
96
A push button emits the signal clicked() when it is activated by
97
the mouse, the Spacebar or by a keyboard shortcut. Connect to
98
this signal to perform the button's action. Push buttons also
99
provide less commonly used signals, for example, pressed() and
102
Command buttons in dialogs are by default auto-default buttons,
103
i.e. they become the default push button automatically when they
104
receive the keyboard input focus. A default button is a push
105
button that is activated when the user presses the Enter or Return
106
key in a dialog. You can change this with setAutoDefault(). Note
107
that auto-default buttons reserve a little extra space which is
108
necessary to draw a default-button indicator. If you do not want
109
this space around your buttons, call setAutoDefault(false).
111
Being so central, the button widget has grown to accommodate a
112
great many variations in the past decade. The Microsoft style
113
guide now shows about ten different states of Windows push buttons
114
and the text implies that there are dozens more when all the
115
combinations of features are taken into consideration.
117
The most important modes or states are:
119
\i Available or not (grayed out, disabled).
120
\i Standard push button, toggling push button or menu button.
121
\i On or off (only for toggling push buttons).
122
\i Default or normal. The default button in a dialog can generally
123
be "clicked" using the Enter or Return key.
124
\i Auto-repeat or not.
125
\i Pressed down or not.
128
As a general rule, use a push button when the application or
129
dialog window performs an action when the user clicks on it (such
130
as Apply, Cancel, Close and Help) \e and when the widget is
131
supposed to have a wide, rectangular shape with a text label.
132
Small, typically square buttons that change the state of the
133
window rather than performing an action (such as the buttons in
134
the top-right corner of the QFileDialog) are not command buttons,
135
but tool buttons. Qt provides a special class (QToolButton) for
138
If you need toggle behavior (see setCheckable()) or a button
139
that auto-repeats the activation signal when being pushed down
140
like the arrows in a scroll bar (see setAutoRepeat()), a command
141
button is probably not what you want. When in doubt, use a tool
144
A variation of a command button is a menu button. These provide
145
not just one command, but several, since when they are clicked
146
they pop up a menu of options. Use the method setMenu() to
147
associate a popup menu with a push button.
149
Other classes of buttons are option buttons (see QRadioButton) and
150
check boxes (see QCheckBox).
152
\inlineimage macintosh-pushbutton.png Screenshot in Macintosh style
153
\inlineimage windows-pushbutton.png Screenshot in Windows style
155
In Qt, the QAbstractButton base class provides most of the modes
156
and other API, and QPushButton provides GUI logic.
157
See QAbstractButton for more information about the API.
159
\sa QToolButton, QRadioButton, QCheckBox, {fowler}{GUI Design Handbook: Push Button}
163
\property QPushButton::autoDefault
164
\brief whether the push button is the auto default button
166
If this property is set to true then the push button is the auto
167
default button in a dialog.
169
In some GUI styles a default button is drawn with an extra frame
170
around it, up to 3 pixels or more. Qt automatically keeps this
171
space free around auto-default buttons, i.e. auto-default buttons
172
may have a slightly larger size hint.
174
This property's default is true for buttons that have a QDialog
175
parent; otherwise it defaults to false.
177
See the \l default property for details of how \l default and
178
auto-default interact.
182
\property QPushButton::default
183
\brief whether the push button is the default button
185
If this property is set to true then the push button will be
186
pressed if the user presses the Enter (or Return) key in a dialog.
188
Regardless of focus, if the user presses Enter: If there is a
189
default button the default button is pressed; otherwise, if
190
there are one or more \l autoDefault buttons the first \l autoDefault
191
button that is next in the tab order is pressed. If there are no
192
default or \l autoDefault buttons only pressing Space on a button
193
with focus, mouse clicking, or using a shortcut will press a
196
In a dialog, only one push button at a time can be the default
197
button. This button is then displayed with an additional frame
198
(depending on the GUI style).
200
The default button behavior is provided only in dialogs. Buttons
201
can always be clicked from the keyboard by pressing Enter (or
202
Return) or the Spacebar when the button has focus.
204
This property's default is false.
208
\property QPushButton::flat
209
\brief whether the border is disabled
211
This property's default is false.
217
Constructs a push button with no text and a \a parent.
220
QPushButton::QPushButton(QWidget *parent)
221
: QAbstractButton(*new QPushButtonPrivate, parent)
228
Constructs a push button with the parent \a parent and the text \a
232
QPushButton::QPushButton(const QString &text, QWidget *parent)
233
: QAbstractButton(*new QPushButtonPrivate, parent)
242
Constructs a push button with an \a icon and a \a text, and a \a parent.
244
Note that you can also pass a QPixmap object as an icon (thanks to
245
the implicit type conversion provided by C++).
248
QPushButton::QPushButton(const QIcon& icon, const QString &text, QWidget *parent)
249
: QAbstractButton(*new QPushButtonPrivate, parent)
259
Destroys the push button.
261
QPushButton::~QPushButton()
265
void QPushButtonPrivate::init()
269
autoDefault = (qobject_cast<QDialog*>(q->window()) != 0);
271
q->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
274
QStyleOptionButton QPushButtonPrivate::getStyleOption() const
276
Q_Q(const QPushButton);
277
QStyleOptionButton opt;
279
opt.features = QStyleOptionButton::None;
281
opt.features |= QStyleOptionButton::Flat;
283
opt.features |= QStyleOptionButton::HasMenu;
284
if (autoDefault || defaultButton)
285
opt.features |= QStyleOptionButton::AutoDefaultButton;
287
opt.features |= QStyleOptionButton::DefaultButton;
289
opt.state |= QStyle::State_Sunken;
291
opt.state |= QStyle::State_On;
293
opt.state |= QStyle::State_Raised;
296
opt.iconSize = q->iconSize();
300
void QPushButton::setAutoDefault(bool enable)
303
if (d->autoDefault == enable)
305
d->autoDefault = enable;
310
bool QPushButton::autoDefault() const
312
Q_D(const QPushButton);
313
return d->autoDefault;
316
void QPushButton::setDefault(bool enable)
319
if (d->defaultButton == enable)
321
d->defaultButton = enable;
323
if (d->defaultButton) {
324
QDialog *dlg = qobject_cast<QDialog*>(window());
326
dlg->d_func()->setMainDefault(this);
330
#ifndef QT_NO_ACCESSIBILITY
331
QAccessible::updateAccessibility(this, 0, QAccessible::StateChanged);
335
bool QPushButton::isDefault() const
337
Q_D(const QPushButton);
338
return d->defaultButton;
344
QSize QPushButton::sizeHint() const
346
Q_D(const QPushButton);
351
QStyleOptionButton opt = d->getStyleOption();
353
// calculate contents size...
355
if (!icon().isNull()) {
356
int ih = opt.iconSize.height();
357
int iw = opt.iconSize.width() + 4;
363
w += style()->pixelMetric(QStyle::PM_MenuButtonIndicator, &opt, this);
365
bool empty = s.isEmpty();
367
s = QString::fromLatin1("XXXX");
368
QFontMetrics fm = fontMetrics();
369
QSize sz = fm.size(Qt::TextShowMnemonic, s);
373
h = qMax(h, sz.height());
374
return (style()->sizeFromContents(QStyle::CT_PushButton, &opt, QSize(w, h), this).
375
expandedTo(QApplication::globalStrut()));
382
void QPushButton::paintEvent(QPaintEvent *)
385
QStylePainter p(this);
386
p.drawControl(QStyle::CE_PushButton, d->getStyleOption());
391
void QPushButton::keyPressEvent(QKeyEvent *e)
397
if (d->autoDefault || d->defaultButton) {
403
QAbstractButton::keyPressEvent(e);
410
void QPushButton::focusInEvent(QFocusEvent *e)
413
if (e->reason() != Qt::PopupFocusReason && d->autoDefault && !d->defaultButton) {
414
d->defaultButton = true;
416
QDialog *dlg = qobject_cast<QDialog*>(window());
418
dlg->d_func()->setDefault(this);
421
QAbstractButton::focusInEvent(e);
427
void QPushButton::focusOutEvent(QFocusEvent *e)
430
if (e->reason() != Qt::PopupFocusReason && d->autoDefault && d->defaultButton) {
432
QDialog *dlg = qobject_cast<QDialog*>(window());
434
dlg->d_func()->setDefault(0);
437
d->defaultButton = false;
440
QAbstractButton::focusOutEvent(e);
441
if (d->menu && d->menu->isVisible()) // restore pressed status
447
Associates the popup menu \a menu with this push button. This
448
turns the button into a menu button, which in some styles will
449
produce a small triangle to the right of the button's text.
451
Ownership of the menu is \e not transferred to the push button.
455
void QPushButton::setMenu(QMenu* menu)
458
if (menu && !d->menu) {
459
disconnect(this, SIGNAL(pressed()), this, SLOT(popupPressed()));
460
connect(this, SIGNAL(pressed()), this, SLOT(popupPressed()));
468
Returns the button's associated popup menu or 0 if no popup menu
473
QMenu* QPushButton::menu() const
475
Q_D(const QPushButton);
480
Shows (pops up) the associated popup menu. If there is no such
481
menu, this function does nothing. This function does not return
482
until the popup menu has been closed by the user.
484
void QPushButton::showMenu()
493
void QPushButtonPrivate::popupPressed()
499
menu->setNoReplayFor(q);
500
bool horizontal = true;
501
#if !defined(QT_NO_TOOLBAR)
502
QToolBar *tb = qobject_cast<QToolBar*>(q->parentWidget());
503
if (tb && tb->orientation() == Qt::Vertical)
506
QRect rect = q->rect();
507
QSize menuSize = menu->sizeHint();
508
QPoint globalPos = q->mapToGlobal(rect.topLeft());
509
int x = globalPos.x();
510
int y = globalPos.y();
512
if (globalPos.y() + rect.height() + menuSize.height() <= qApp->desktop()->height()) {
515
y -= menuSize.height();
517
if (q->layoutDirection() == Qt::RightToLeft)
518
x += rect.width() - menuSize.width();
520
if (globalPos.x() + rect.width() + menu->sizeHint().width() <= qApp->desktop()->width())
523
x -= menuSize.width();
526
QMetaObject::addGuard(&guard);
527
menu->exec(QPoint(x, y));
530
QMetaObject::removeGuard(&guard);
534
void QPushButton::setFlat(bool flat)
544
bool QPushButton::isFlat() const
546
Q_D(const QPushButton);
552
Use one of the constructors that doesn't take the \a name
553
argument and then use setObjectName() instead.
555
QPushButton::QPushButton(QWidget *parent, const char *name)
556
: QAbstractButton(*new QPushButtonPrivate, parent)
564
Use one of the constructors that doesn't take the \a name
565
argument and then use setObjectName() instead.
567
QPushButton::QPushButton(const QString &text, QWidget *parent, const char *name)
568
: QAbstractButton(*new QPushButtonPrivate, parent)
577
Use one of the constructors that doesn't take the \a name
578
argument and then use setObjectName() instead.
580
QPushButton::QPushButton(const QIcon& icon, const QString &text, QWidget *parent, const char *name)
581
: QAbstractButton(*new QPushButtonPrivate, parent)
592
\fn void QPushButton::openPopup()
594
Use showMenu() instead.
598
\fn bool QPushButton::isMenuButton() const
600
Use menu() != 0 instead.
604
\fn void QPushButton::setPopup(QMenu* popup)
606
Use setMenu() instead.
610
\fn QMenu* QPushButton::popup() const
616
#include "moc_qpushbutton.cpp"