1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29
30#include <QtTest/QtTest>
31
32
33#include "qbuttongroup.h"
34#include <qaction.h>
35#include <qapplication.h>
36#include <qdialog.h>
37#include <qlayout.h>
38#include <qgroupbox.h>
39#include <qradiobutton.h>
40#include <qpushbutton.h>
41#include <qlineedit.h>
42#include <qtoolbutton.h>
43#ifdef Q_OS_MAC
44#include <qsettings.h>
45#endif
46
47class SpecialRadioButton: public QRadioButton
48{
49public:
50 SpecialRadioButton(QWidget *parent) : QRadioButton(parent)
51 { }
52
53protected:
54 void focusInEvent(QFocusEvent *)
55 {
56 QCoreApplication::postEvent(receiver: this, event: new QKeyEvent(QEvent::KeyPress,
57 Qt::Key_Down, Qt::NoModifier));
58 }
59};
60
61class TestPushButton : public QPushButton
62{
63public:
64 TestPushButton(QWidget *parent = nullptr)
65 : QPushButton(parent)
66 {}
67 TestPushButton(const QString &title, QWidget *parent = nullptr)
68 : QPushButton(title, parent)
69 {}
70
71protected:
72 bool hitButton(const QPoint &pos) const override
73 {
74 return rect().contains(p: pos);
75 }
76};
77
78#include <qbuttongroup.h>
79
80class tst_QButtonGroup : public QObject
81{
82Q_OBJECT
83
84private slots:
85 void arrowKeyNavigation();
86 void keyNavigationPushButtons();
87 void exclusive();
88 void exclusiveWithActions();
89 void testSignals();
90 void checkedButton();
91
92 void task106609();
93
94 void autoIncrementId();
95
96 void task209485_removeFromGroupInEventHandler_data();
97 void task209485_removeFromGroupInEventHandler();
98};
99
100QT_BEGIN_NAMESPACE
101extern bool Q_GUI_EXPORT qt_tab_all_widgets();
102QT_END_NAMESPACE
103
104
105void tst_QButtonGroup::arrowKeyNavigation()
106{
107 if (!qt_tab_all_widgets())
108 QSKIP("This test requires full keyboard control to be enabled.");
109
110 if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland"), cs: Qt::CaseInsensitive))
111 QSKIP("Wayland: This fails. Figure out why.");
112
113 QDialog dlg(0);
114 QHBoxLayout layout(&dlg);
115 QGroupBox g1("1", &dlg);
116 QHBoxLayout g1layout(&g1);
117 QRadioButton bt1("Radio1", &g1);
118 TestPushButton pb("PB", &g1);
119 QLineEdit le(&g1);
120 QRadioButton bt2("Radio2", &g1);
121 g1layout.addWidget(&bt1);
122 g1layout.addWidget(&pb);
123 g1layout.addWidget(&le);
124 g1layout.addWidget(&bt2);
125
126 // create a mixed button group with radion buttons and push
127 // buttons. Not very useful, but it tests borderline cases wrt
128 // focus handling.
129 QButtonGroup bgrp1(&g1);
130 bgrp1.addButton(&bt1);
131 bgrp1.addButton(&pb);
132 bgrp1.addButton(&bt2);
133
134 QGroupBox g2("2", &dlg);
135 QVBoxLayout g2layout(&g2);
136 // we don't need a button group here, because radio buttons are
137 // auto exclusive, i.e. they group themselves in he same parent
138 // widget.
139 QRadioButton bt3("Radio3", &g2);
140 QRadioButton bt4("Radio4", &g2);
141 g2layout.addWidget(&bt3);
142 g2layout.addWidget(&bt4);
143
144 layout.addWidget(&g1);
145 layout.addWidget(&g2);
146
147 dlg.show();
148 qApp->setActiveWindow(&dlg);
149 QVERIFY(QTest::qWaitForWindowActive(&dlg));
150
151 bt1.setFocus();
152
153 QTRY_VERIFY(bt1.hasFocus());
154
155 QTest::keyClick(widget: &bt1, key: Qt::Key_Right);
156 QVERIFY(pb.hasFocus());
157 QTest::keyClick(widget: &pb, key: Qt::Key_Right);
158 QVERIFY(bt2.hasFocus());
159 QTest::keyClick(widget: &bt2, key: Qt::Key_Right);
160 QVERIFY(bt2.hasFocus());
161 QTest::keyClick(widget: &bt2, key: Qt::Key_Left);
162 QVERIFY(pb.hasFocus());
163 QTest::keyClick(widget: &pb, key: Qt::Key_Left);
164 QVERIFY(bt1.hasFocus());
165
166 QTest::keyClick(widget: &bt1, key: Qt::Key_Tab);
167 QVERIFY(pb.hasFocus());
168 QTest::keyClick(widget: &pb, key: Qt::Key_Tab);
169
170 QVERIFY(le.hasFocus());
171 QCOMPARE(le.selectedText(), le.text());
172 QTest::keyClick(widget: &le, key: Qt::Key_Tab);
173
174 QVERIFY(bt2.hasFocus());
175 QTest::keyClick(widget: &bt2, key: Qt::Key_Tab);
176 QVERIFY(bt3.hasFocus());
177
178 QTest::keyClick(widget: &bt3, key: Qt::Key_Down);
179 QVERIFY(bt4.hasFocus());
180 QTest::keyClick(widget: &bt4, key: Qt::Key_Down);
181 QVERIFY(bt4.hasFocus());
182
183 QTest::keyClick(widget: &bt4, key: Qt::Key_Up);
184 QVERIFY(bt3.hasFocus());
185 QTest::keyClick(widget: &bt3, key: Qt::Key_Up);
186 QVERIFY(bt3.hasFocus());
187}
188
189/*
190 Test that tab and arrow key navigation through buttons
191 in an invisible button group works as expected. Tabbing
192 into the group should give focus to the checked button,
193 and arrow navigation should change the checked button and
194 move focus.
195*/
196void tst_QButtonGroup::keyNavigationPushButtons()
197{
198 if (!qt_tab_all_widgets())
199 QSKIP("This test requires full keyboard control to be enabled.");
200
201 QDialog dlg(nullptr);
202 QLineEdit *le1 = new QLineEdit;
203 le1->setObjectName("le1");
204 QPushButton *pb1 = new QPushButton("Exclusive 1");
205 pb1->setObjectName("pb1");
206 pb1->setCheckable(true);
207 pb1->setChecked(true);
208 QPushButton *pb2 = new QPushButton("Exclusive 2");
209 pb2->setObjectName("pb2");
210 pb2->setCheckable(true);
211 QPushButton *pb3 = new QPushButton("Exclusive 3");
212 pb3->setObjectName("pb3");
213 pb3->setCheckable(true);
214 QLineEdit *le2 = new QLineEdit;
215 le2->setObjectName("le2");
216
217 QVBoxLayout* layout = new QVBoxLayout(&dlg);
218 layout->addWidget(le1);
219 layout->addWidget(pb1);
220 layout->addWidget(pb2);
221 layout->addWidget(pb3);
222 layout->addWidget(le2);
223
224 QButtonGroup *buttonGroup = new QButtonGroup;
225 buttonGroup->addButton(pb1);
226 buttonGroup->addButton(pb2);
227 buttonGroup->addButton(pb3);
228
229 dlg.show();
230 qApp->setActiveWindow(&dlg);
231 if (!QTest::qWaitForWindowActive(widget: &dlg))
232 QSKIP("Window activation failed, skipping test");
233
234 QVERIFY2(le1->hasFocus(), qPrintable(qApp->focusWidget()->objectName()));
235 QTest::keyClick(qApp->focusWidget(), key: Qt::Key_Tab);
236 QVERIFY2(pb1->hasFocus(), qPrintable(qApp->focusWidget()->objectName()));
237 QVERIFY2(pb1->isChecked(), qPrintable(buttonGroup->checkedButton()->objectName()));
238 QTest::keyClick(qApp->focusWidget(), key: Qt::Key_Down);
239 QVERIFY2(pb2->hasFocus(), qPrintable(qApp->focusWidget()->objectName()));
240 QVERIFY2(pb2->isChecked(), qPrintable(buttonGroup->checkedButton()->objectName()));
241 QTest::keyClick(qApp->focusWidget(), key: Qt::Key_Down);
242 QVERIFY2(pb3->hasFocus(), qPrintable(qApp->focusWidget()->objectName()));
243 QVERIFY2(pb3->isChecked(), qPrintable(buttonGroup->checkedButton()->objectName()));
244 QTest::keyClick(qApp->focusWidget(), key: Qt::Key_Up);
245 QVERIFY2(pb2->hasFocus(), qPrintable(qApp->focusWidget()->objectName()));
246 QVERIFY2(pb2->isChecked(), qPrintable(buttonGroup->checkedButton()->objectName()));
247 QTest::keyClick(qApp->focusWidget(), key: Qt::Key_Tab);
248 QVERIFY2(le2->hasFocus(), qPrintable(qApp->focusWidget()->objectName()));
249 QTest::keyClick(qApp->focusWidget(), key: Qt::Key_Backtab);
250 QVERIFY2(pb2->hasFocus(), qPrintable(qApp->focusWidget()->objectName()));
251 QVERIFY2(pb2->isChecked(), qPrintable(buttonGroup->checkedButton()->objectName()));
252 QTest::keyClick(qApp->focusWidget(), key: Qt::Key_Backtab);
253 QVERIFY2(le1->hasFocus(), qPrintable(qApp->focusWidget()->objectName()));
254}
255
256void tst_QButtonGroup::exclusiveWithActions()
257{
258 QDialog dlg(0);
259 QHBoxLayout layout(&dlg);
260 QAction *action1 = new QAction("Action 1", &dlg);
261 action1->setCheckable(true);
262 QAction *action2 = new QAction("Action 2", &dlg);
263 action2->setCheckable(true);
264 QAction *action3 = new QAction("Action 3", &dlg);
265 action3->setCheckable(true);
266 QToolButton *toolButton1 = new QToolButton(&dlg);
267 QToolButton *toolButton2 = new QToolButton(&dlg);
268 QToolButton *toolButton3 = new QToolButton(&dlg);
269 toolButton1->setDefaultAction(action1);
270 toolButton2->setDefaultAction(action2);
271 toolButton3->setDefaultAction(action3);
272 layout.addWidget(toolButton1);
273 layout.addWidget(toolButton2);
274 layout.addWidget(toolButton3);
275 QButtonGroup *buttonGroup = new QButtonGroup( &dlg );
276 buttonGroup->setExclusive(true);
277 buttonGroup->addButton(toolButton1, id: 1);
278 buttonGroup->addButton(toolButton2, id: 2);
279 buttonGroup->addButton(toolButton3, id: 3);
280 dlg.show();
281
282 QTest::mouseClick(widget: toolButton1, button: Qt::LeftButton);
283 QVERIFY(toolButton1->isChecked());
284 QVERIFY(action1->isChecked());
285 QVERIFY(!toolButton2->isChecked());
286 QVERIFY(!toolButton3->isChecked());
287 QVERIFY(!action2->isChecked());
288 QVERIFY(!action3->isChecked());
289
290 QTest::mouseClick(widget: toolButton2, button: Qt::LeftButton);
291 QVERIFY(toolButton2->isChecked());
292 QVERIFY(action2->isChecked());
293 QVERIFY(!toolButton1->isChecked());
294 QVERIFY(!toolButton3->isChecked());
295 QVERIFY(!action1->isChecked());
296 QVERIFY(!action3->isChecked());
297
298 QTest::mouseClick(widget: toolButton3, button: Qt::LeftButton);
299 QVERIFY(toolButton3->isChecked());
300 QVERIFY(action3->isChecked());
301 QVERIFY(!toolButton1->isChecked());
302 QVERIFY(!toolButton2->isChecked());
303 QVERIFY(!action1->isChecked());
304 QVERIFY(!action2->isChecked());
305
306 QTest::mouseClick(widget: toolButton2, button: Qt::LeftButton);
307 QVERIFY(toolButton2->isChecked());
308 QVERIFY(action2->isChecked());
309 QVERIFY(!toolButton1->isChecked());
310 QVERIFY(!toolButton3->isChecked());
311 QVERIFY(!action1->isChecked());
312 QVERIFY(!action3->isChecked());
313}
314
315void tst_QButtonGroup::exclusive()
316{
317 QDialog dlg(0);
318 QHBoxLayout layout(&dlg);
319 TestPushButton *pushButton1 = new TestPushButton(&dlg);
320 TestPushButton *pushButton2 = new TestPushButton(&dlg);
321 TestPushButton *pushButton3 = new TestPushButton(&dlg);
322 pushButton1->setCheckable(true);
323 pushButton2->setCheckable(true);
324 pushButton3->setCheckable(true);
325 layout.addWidget(pushButton1);
326 layout.addWidget(pushButton2);
327 layout.addWidget(pushButton3);
328 QButtonGroup *buttonGroup = new QButtonGroup( &dlg );
329 buttonGroup->setExclusive(true);
330 buttonGroup->addButton(pushButton1, id: 1);
331 buttonGroup->addButton(pushButton2, id: 2);
332 buttonGroup->addButton(pushButton3, id: 3);
333 dlg.show();
334
335 QTest::mouseClick(widget: pushButton1, button: Qt::LeftButton);
336 QVERIFY(pushButton1->isChecked());
337 QVERIFY(!pushButton2->isChecked());
338 QVERIFY(!pushButton3->isChecked());
339
340 QTest::mouseClick(widget: pushButton2, button: Qt::LeftButton);
341 QVERIFY(pushButton2->isChecked());
342 QVERIFY(!pushButton1->isChecked());
343 QVERIFY(!pushButton3->isChecked());
344
345 QTest::mouseClick(widget: pushButton3, button: Qt::LeftButton);
346 QVERIFY(pushButton3->isChecked());
347 QVERIFY(!pushButton1->isChecked());
348 QVERIFY(!pushButton2->isChecked());
349
350 QTest::mouseClick(widget: pushButton2, button: Qt::LeftButton);
351 QVERIFY(pushButton2->isChecked());
352 QVERIFY(!pushButton1->isChecked());
353 QVERIFY(!pushButton3->isChecked());
354}
355
356void tst_QButtonGroup::testSignals()
357{
358 QButtonGroup buttons;
359 TestPushButton pb1;
360 TestPushButton pb2;
361 TestPushButton pb3;
362 buttons.addButton(&pb1);
363 buttons.addButton(&pb2, id: 23);
364 buttons.addButton(&pb3);
365
366 qRegisterMetaType<QAbstractButton *>(typeName: "QAbstractButton *");
367 QSignalSpy clickedSpy(&buttons, SIGNAL(buttonClicked(QAbstractButton*)));
368 QSignalSpy clickedIdSpy(&buttons, SIGNAL(idClicked(int)));
369 QSignalSpy pressedSpy(&buttons, SIGNAL(buttonPressed(QAbstractButton*)));
370 QSignalSpy pressedIdSpy(&buttons, SIGNAL(idPressed(int)));
371 QSignalSpy releasedSpy(&buttons, SIGNAL(buttonReleased(QAbstractButton*)));
372 QSignalSpy releasedIdSpy(&buttons, SIGNAL(idReleased(int)));
373
374 pb1.animateClick();
375 QTestEventLoop::instance().enterLoop(secs: 1);
376
377 QCOMPARE(clickedSpy.count(), 1);
378 QCOMPARE(clickedIdSpy.count(), 1);
379
380 int expectedId = -2;
381
382 QCOMPARE(clickedIdSpy.takeFirst().at(0).toInt(), expectedId);
383 QCOMPARE(pressedSpy.count(), 1);
384 QCOMPARE(pressedIdSpy.count(), 1);
385 QCOMPARE(pressedIdSpy.takeFirst().at(0).toInt(), expectedId);
386 QCOMPARE(releasedSpy.count(), 1);
387 QCOMPARE(releasedIdSpy.count(), 1);
388 QCOMPARE(releasedIdSpy.takeFirst().at(0).toInt(), expectedId);
389
390 clickedSpy.clear();
391 clickedIdSpy.clear();
392 pressedSpy.clear();
393 pressedIdSpy.clear();
394 releasedSpy.clear();
395 releasedIdSpy.clear();
396
397 pb2.animateClick();
398 QTestEventLoop::instance().enterLoop(secs: 1);
399
400 QCOMPARE(clickedSpy.count(), 1);
401 QCOMPARE(clickedIdSpy.count(), 1);
402 QCOMPARE(clickedIdSpy.takeFirst().at(0).toInt(), 23);
403 QCOMPARE(pressedSpy.count(), 1);
404 QCOMPARE(pressedIdSpy.count(), 1);
405 QCOMPARE(pressedIdSpy.takeFirst().at(0).toInt(), 23);
406 QCOMPARE(releasedSpy.count(), 1);
407 QCOMPARE(releasedIdSpy.count(), 1);
408 QCOMPARE(releasedIdSpy.takeFirst().at(0).toInt(), 23);
409
410
411 QSignalSpy toggledSpy(&buttons, SIGNAL(buttonToggled(QAbstractButton*, bool)));
412 QSignalSpy toggledIdSpy(&buttons, SIGNAL(idToggled(int, bool)));
413
414 pb1.setCheckable(true);
415 pb2.setCheckable(true);
416 pb1.toggle();
417 QCOMPARE(toggledSpy.count(), 1);
418 QCOMPARE(toggledIdSpy.count(), 1);
419
420 pb2.toggle();
421 QCOMPARE(toggledSpy.count(), 3); // equals 3 since pb1 and pb2 are both toggled
422 QCOMPARE(toggledIdSpy.count(), 3);
423
424 pb1.setCheckable(false);
425 pb2.setCheckable(false);
426 pb1.toggle();
427 QCOMPARE(toggledSpy.count(), 3);
428 QCOMPARE(toggledIdSpy.count(), 3);
429}
430
431void tst_QButtonGroup::task106609()
432{
433 // task is:
434 // sometimes, only one of the two signals in QButtonGroup get emitted
435 // they get emitted when using the mouse, but when using the keyboard, only one is
436 //
437
438 QDialog dlg(0);
439 QButtonGroup *buttons = new QButtonGroup(&dlg);
440 QVBoxLayout *vbox = new QVBoxLayout(&dlg);
441
442 SpecialRadioButton *radio1 = new SpecialRadioButton(&dlg);
443 radio1->setText("radio1");
444 SpecialRadioButton *radio2 = new SpecialRadioButton(&dlg);
445 radio2->setText("radio2");
446 QRadioButton *radio3 = new QRadioButton(&dlg);
447 radio3->setText("radio3");
448
449 buttons->addButton(radio1, id: 1);
450 vbox->addWidget(radio1);
451 buttons->addButton(radio2, id: 2);
452 vbox->addWidget(radio2);
453 buttons->addButton(radio3, id: 3);
454 vbox->addWidget(radio3);
455 dlg.show();
456 QVERIFY(QTest::qWaitForWindowExposed(&dlg));
457
458 qRegisterMetaType<QAbstractButton*>(typeName: "QAbstractButton*");
459 QSignalSpy spy1(buttons, SIGNAL(buttonClicked(QAbstractButton*)));
460 QSignalSpy spy2(buttons, SIGNAL(buttonClicked(int)));
461
462 QApplication::setActiveWindow(&dlg);
463 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&dlg));
464
465 radio1->setFocus();
466 radio1->setChecked(true);
467 QTestEventLoop::instance().enterLoop(secs: 1);
468
469 //qDebug() << "int:" << spy2.count() << "QAbstractButton*:" << spy1.count();
470 QCOMPARE(spy2.count(), 2);
471 QCOMPARE(spy1.count(), 2);
472}
473
474void tst_QButtonGroup::checkedButton()
475{
476 QButtonGroup buttons;
477 buttons.setExclusive(false);
478 TestPushButton pb1;
479 pb1.setCheckable(true);
480 TestPushButton pb2;
481 pb2.setCheckable(true);
482 buttons.addButton(&pb1);
483 buttons.addButton(&pb2, id: 23);
484
485 QVERIFY(!buttons.checkedButton());
486 pb1.setChecked(true);
487 QCOMPARE(buttons.checkedButton(), &pb1);
488 pb2.setChecked(true);
489 QCOMPARE(buttons.checkedButton(), &pb2);
490 pb2.setChecked(false);
491 QCOMPARE(buttons.checkedButton(), &pb1);
492 pb1.setChecked(false);
493 QVERIFY(!buttons.checkedButton());
494
495 buttons.setExclusive(true);
496 QVERIFY(!buttons.checkedButton());
497 pb1.setChecked(true);
498 QCOMPARE(buttons.checkedButton(), &pb1);
499 pb2.setChecked(true);
500 QCOMPARE(buttons.checkedButton(), &pb2);
501 // checked button cannot be unchecked
502 pb2.setChecked(false);
503 QCOMPARE(buttons.checkedButton(), &pb2);
504}
505
506class task209485_ButtonDeleter : public QObject
507{
508 Q_OBJECT
509
510public:
511 task209485_ButtonDeleter(QButtonGroup *group, bool deleteButton)
512 : group(group)
513 , deleteButton(deleteButton)
514 {
515 connect(asender: group, SIGNAL(buttonClicked(int)), SLOT(buttonClicked(int)));
516 }
517
518private slots:
519 void buttonClicked(int)
520 {
521 if (deleteButton)
522 group->removeButton(group->buttons().first());
523 }
524
525private:
526 QButtonGroup *group;
527 bool deleteButton;
528};
529
530void tst_QButtonGroup::task209485_removeFromGroupInEventHandler_data()
531{
532 QTest::addColumn<bool>(name: "deleteButton");
533 QTest::addColumn<int>(name: "signalCount");
534 QTest::newRow(dataTag: "buttonPress 1") << true << 1;
535 QTest::newRow(dataTag: "buttonPress 2") << false << 2;
536}
537
538void tst_QButtonGroup::task209485_removeFromGroupInEventHandler()
539{
540 QFETCH(bool, deleteButton);
541 QFETCH(int, signalCount);
542 qRegisterMetaType<QAbstractButton *>(typeName: "QAbstractButton *");
543
544 TestPushButton *button = new TestPushButton;
545 QButtonGroup group;
546 group.addButton(button);
547
548 task209485_ButtonDeleter buttonDeleter(&group, deleteButton);
549
550 QSignalSpy spy1(&group, SIGNAL(buttonClicked(QAbstractButton*)));
551 QSignalSpy spy2(&group, SIGNAL(buttonClicked(int)));
552
553 // NOTE: Reintroducing the bug of this task will cause the following line to crash:
554 QTest::mouseClick(widget: button, button: Qt::LeftButton);
555
556 QCOMPARE(spy1.count() + spy2.count(), signalCount);
557}
558
559void tst_QButtonGroup::autoIncrementId()
560{
561 QDialog dlg(0);
562 QButtonGroup *buttons = new QButtonGroup(&dlg);
563 QVBoxLayout *vbox = new QVBoxLayout(&dlg);
564
565 QRadioButton *radio1 = new QRadioButton(&dlg);
566 radio1->setText("radio1");
567 QRadioButton *radio2 = new QRadioButton(&dlg);
568 radio2->setText("radio2");
569 QRadioButton *radio3 = new QRadioButton(&dlg);
570 radio3->setText("radio3");
571
572 buttons->addButton(radio1);
573 vbox->addWidget(radio1);
574 buttons->addButton(radio2);
575 vbox->addWidget(radio2);
576 buttons->addButton(radio3);
577 vbox->addWidget(radio3);
578
579 radio1->setChecked(true);
580
581 QCOMPARE(buttons->id(radio1), -2);
582 QCOMPARE(buttons->id(radio2), -3);
583 QCOMPARE(buttons->id(radio3), -4);
584
585 dlg.show();
586}
587
588QTEST_MAIN(tst_QButtonGroup)
589#include "tst_qbuttongroup.moc"
590

source code of qtbase/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp