C++/Qt/Signal

Материал из C\C++ эксперт
Перейти к: навигация, поиск

A Slot Responds to a Signal

<source lang="cpp">

  1. include <QApplication>
  2. include <QPushButton>

int main(int argc, char *argv[]) {

   QApplication a(argc, argv);
   QPushButton button("Quit");
   button.show();
   QObject::connect(&button, SIGNAL(clicked()),&a, SLOT(quit()));
   return a.exec();

}


 </source>


event filters

<source lang="cpp"> /****************************************************************************

    • Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    • All rights reserved.
    • Contact: Nokia Corporation (qt-info@nokia.com)
    • This file is part of the documentation of the Qt Toolkit.
    • $QT_BEGIN_LICENSE:LGPL$
    • Commercial Usage
    • Licensees holding valid Qt Commercial licenses may use this file in
    • accordance with the Qt Commercial License Agreement provided with the
    • Software or, alternatively, in accordance with the terms contained in
    • a written agreement between you and Nokia.
    • GNU Lesser General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU Lesser
    • General Public License version 2.1 as published by the Free Software
    • Foundation and appearing in the file LICENSE.LGPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU Lesser General Public License version 2.1 requirements
    • will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    • In addition, as a special exception, Nokia gives you certain additional
    • rights. These rights are described in the Nokia Qt LGPL Exception
    • version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    • GNU General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU
    • General Public License version 3.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 the GNU General Public License version 3.0 requirements will be
    • met: http://www.gnu.org/copyleft/gpl.html.
    • If you have questions regarding the use of this file, please contact
    • Nokia at qt-info@nokia.com.
    • $QT_END_LICENSE$
                                                                                                                                                        • /
  1. ifndef FILTEROBJECT_H
  2. define FILTEROBJECT_H
  3. include <QObject>

class FilterObject : public QObject {

   Q_OBJECT

public:

   FilterObject(QObject *parent = 0);
   bool eventFilter(QObject *object, QEvent *event);
   void setFilteredObject(QObject *object);

private:

   QObject *target;

};

  1. endif



  1. include <QtGui>
  2. include "filterobject.h"

FilterObject::FilterObject(QObject *parent)

   : QObject(parent), target(0)

{ } bool FilterObject::eventFilter(QObject *object, QEvent *event) {

   if (object == target && event->type() == QEvent::KeyPress) {
       QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
       if (keyEvent->key() == Qt::Key_Tab) {
           // Special tab handling
           return true;
       } else
           return false;
   }
   return false;

} void FilterObject::setFilteredObject(QObject *object) {

   if (target)
       target->removeEventFilter(this);
   target = object;
   if (target)
       target->installEventFilter(this);

}



  1. include <QApplication>
  2. include <QTextEdit>
  3. include "filterobject.h"

int main(int argc, char *argv[]) {

   QApplication app(argc, argv);
   QTextEdit editor;
   FilterObject filter;
   filter.setFilteredObject(&editor);
   editor.show();
   return app.exec();

}


 </source>


Inherited slot

<source lang="cpp"> /****************************************************************************

    • Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    • All rights reserved.
    • Contact: Nokia Corporation (qt-info@nokia.com)
    • This file is part of the documentation of the Qt Toolkit.
    • $QT_BEGIN_LICENSE:LGPL$
    • Commercial Usage
    • Licensees holding valid Qt Commercial licenses may use this file in
    • accordance with the Qt Commercial License Agreement provided with the
    • Software or, alternatively, in accordance with the terms contained in
    • a written agreement between you and Nokia.
    • GNU Lesser General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU Lesser
    • General Public License version 2.1 as published by the Free Software
    • Foundation and appearing in the file LICENSE.LGPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU Lesser General Public License version 2.1 requirements
    • will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    • In addition, as a special exception, Nokia gives you certain additional
    • rights. These rights are described in the Nokia Qt LGPL Exception
    • version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    • GNU General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU
    • General Public License version 3.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 the GNU General Public License version 3.0 requirements will be
    • met: http://www.gnu.org/copyleft/gpl.html.
    • If you have questions regarding the use of this file, please contact
    • Nokia at qt-info@nokia.com.
    • $QT_END_LICENSE$
                                                                                                                                                        • /
  1. ifndef WINDOW_H
  2. define WINDOW_H
  3. include <QPushButton>

//! [Button class with reimplemented slot] class Button : public QPushButton {

   Q_OBJECT

public:

   Button(QWidget *parent = 0);

public slots:

   void animateClick();

}; //! [Button class with reimplemented slot]

  1. endif


  1. include <QDebug>
  2. include "button.h"

Button::Button(QWidget *parent)

   : QPushButton(parent)

{ } void Button::animateClick() {

   qDebug() << "Extra code goes here...";
   QPushButton::animateClick();

}


  1. include <QApplication>
  2. include <QDebug>
  3. include <QHBoxLayout>
  4. include <QLineEdit>
  5. include <QMetaMethod>
  6. include <QWidget>
  7. include "button.h"

int main(int argc, char *argv[]) {

   QApplication app(argc, argv);
   QWidget window;
   QHBoxLayout *layout = new QHBoxLayout(&window);
   QLineEdit *lineEdit = new QLineEdit;
   Button *button = new Button;
   QObject::connect(lineEdit, SIGNAL(returnPressed()), button, SLOT(animateClick()));
   layout->addWidget(lineEdit);
   layout->addWidget(button);
   window.show();
   for (int i = 0; i < button->metaObject()->methodCount(); ++i)
       qDebug() << i << button->metaObject()->method(i).signature();
   return app.exec();

}


 </source>


Mark method with Q_INVOKABLE

<source lang="cpp"> /****************************************************************************

    • Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    • All rights reserved.
    • Contact: Nokia Corporation (qt-info@nokia.com)
    • This file is part of the documentation of the Qt Toolkit.
    • $QT_BEGIN_LICENSE:LGPL$
    • Commercial Usage
    • Licensees holding valid Qt Commercial licenses may use this file in
    • accordance with the Qt Commercial License Agreement provided with the
    • Software or, alternatively, in accordance with the terms contained in
    • a written agreement between you and Nokia.
    • GNU Lesser General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU Lesser
    • General Public License version 2.1 as published by the Free Software
    • Foundation and appearing in the file LICENSE.LGPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU Lesser General Public License version 2.1 requirements
    • will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    • In addition, as a special exception, Nokia gives you certain additional
    • rights. These rights are described in the Nokia Qt LGPL Exception
    • version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    • GNU General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU
    • General Public License version 3.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 the GNU General Public License version 3.0 requirements will be
    • met: http://www.gnu.org/copyleft/gpl.html.
    • If you have questions regarding the use of this file, please contact
    • Nokia at qt-info@nokia.com.
    • $QT_END_LICENSE$
                                                                                                                                                        • /
  1. ifndef WINDOW_H
  2. define WINDOW_H
  3. include <QWidget>

//! [Window class with invokable method] class Window : public QWidget {

   Q_OBJECT

public:

   Window();
   void normalMethod();
   Q_INVOKABLE void invokableMethod();

}; //! [Window class with invokable method]

  1. endif


  1. include "window.h"

Window::Window() { } void Window::normalMethod() {

   // Cannot be called by the meta-object system.
   show();

} void Window::invokableMethod() {

   // Can be called by the meta-object system.
   show();

}


  1. include <QApplication>
  2. include <QDebug>
  3. include "window.h"

int main(int argc, char *argv[]) {

   QApplication app(argc, argv);
   Window window;
   qDebug() << window.metaObject()->methodCount();
   window.show();
   return app.exec();

}


 </source>


Multi-event handlers

<source lang="cpp">

  1. include <QApplication>
  2. include <QVBoxLayout>
  3. include <QLabel>
  4. include <QSpinBox>
  5. include <QSlider>

int main(int argc, char *argv[]) {

   QApplication a(argc, argv);
   QWidgetwindow;
   QVBoxLayout* mainLayout = new QVBoxLayout(&window);
   QLabel* label = new QLabel("0");
   QSpinBox* spinBox =new QSpinBox;
   QSlider* slider = new QSlider(Qt::Horizontal);
   mainLayout->addWidget(label);
   mainLayout->addWidget(spinBox);
   mainLayout->addWidget(slider);
   QObject::connect(spinBox, SIGNAL(valueChanged(int)),label, SLOT(setNum(int)));
   QObject::connect(spinBox, SIGNAL(valueChanged(int)),slider, SLOT(setValue(int)));
   QObject::connect(slider, SIGNAL(valueChanged(int)),label, SLOT(setNum(int)));
   QObject::connect(slider, SIGNAL(valueChanged(int)),spinBox, SLOT(setValue(int)));
   window.show();
   return a.exec();

}


 </source>


QSignal mapper

<source lang="cpp">

/****************************************************************************

    • Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    • All rights reserved.
    • Contact: Nokia Corporation (qt-info@nokia.com)
    • This file is part of the documentation of the Qt Toolkit.
    • $QT_BEGIN_LICENSE:LGPL$
    • Commercial Usage
    • Licensees holding valid Qt Commercial licenses may use this file in
    • accordance with the Qt Commercial License Agreement provided with the
    • Software or, alternatively, in accordance with the terms contained in
    • a written agreement between you and Nokia.
    • GNU Lesser General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU Lesser
    • General Public License version 2.1 as published by the Free Software
    • Foundation and appearing in the file LICENSE.LGPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU Lesser General Public License version 2.1 requirements
    • will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    • In addition, as a special exception, Nokia gives you certain additional
    • rights. These rights are described in the Nokia Qt LGPL Exception
    • version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    • GNU General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU
    • General Public License version 3.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 the GNU General Public License version 3.0 requirements will be
    • met: http://www.gnu.org/copyleft/gpl.html.
    • If you have questions regarding the use of this file, please contact
    • Nokia at qt-info@nokia.com.
    • $QT_END_LICENSE$
                                                                                                                                                        • /
  1. ifndef BUTTONWIDGET_H
  2. define BUTTONWIDGET_H
  3. include <qwidget.h>

class QSignalMapper; class QString; class QStringList;

class ButtonWidget : public QWidget {

   Q_OBJECT

public:

   ButtonWidget(QStringList texts, QWidget *parent = 0);

signals:

   void clicked(const QString &text);

private:

   QSignalMapper *signalMapper;

};

  1. endif


  1. include <QtGui>
  2. include "buttonwidget.h"

ButtonWidget::ButtonWidget(QStringList texts, QWidget *parent)

   : QWidget(parent)

{

   signalMapper = new QSignalMapper(this);
   QGridLayout *gridLayout = new QGridLayout;
   for (int i = 0; i < texts.size(); ++i) {
 QPushButton *button = new QPushButton(texts[i]);
 connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));

 signalMapper->setMapping(button, texts[i]);
 gridLayout->addWidget(button, i / 3, i % 3);
   }
   connect(signalMapper, SIGNAL(mapped(const QString &)),

           this, SIGNAL(clicked(const QString &)));
   setLayout(gridLayout);

}


  1. include <QMainWindow>
  2. include <QStatusBar>

class MainWindow : public QMainWindow {

   Q_OBJECT

public:

   MainWindow()
   {
       statusBar()->showMessage(tr("Ready"));
   }

public slots:

   void buttonPressed(const QString &text)
   {
       statusBar()->showMessage(tr("Chose %1").arg(text));
   }

};


  1. include <QApplication>
  2. include "buttonwidget.h"
  3. include "mainwindow.h"

int main(int argc, char *argv[]) {

   QApplication app(argc, argv);
   QStringList texts;
   texts << "January" << "February" << "March" << "April"
         << "May" << "June" << "July" << "August"
         << "September" << "October" << "November"
         << "December";
   MainWindow *mw = new MainWindow;
   ButtonWidget *buttons = new ButtonWidget(texts, mw);
   mw->setCentralWidget(buttons);
   mw->show();
   QObject::connect(buttons, SIGNAL(clicked(const QString &)),
                    mw, SLOT(buttonPressed(const QString &)));
   return app.exec();

}


 </source>


Qt signals and slots

<source lang="cpp"> /*

* Copyright (c) 2006-2007, Johan Thelin
* 
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, 
* are permitted provided that the following conditions are met:
* 
*     * Redistributions of source code must retain the above copyright notice, 
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice,  
*       this list of conditions and the following disclaimer in the documentation 
*       and/or other materials provided with the distribution.
*     * Neither the name of APress nor the names of its contributors 
*       may be used to endorse or promote products derived from this software 
*       without specific prior written permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

  1. include "myclass.h"

MyClass::MyClass( const QString &text, QObject *parent ) : QObject( parent ) {

 m_text = text;

} const QString &MyClass::text() const {

 return m_text;

} void MyClass::setText( const QString &text ) {

 if( m_text == text )
   return;
 m_text = text;
 emit textChanged( m_text );

} int MyClass::getLengthOfText() const {

 return m_text.size();

}

Chapter01\signals-and-slots\myclass.h /*

* Copyright (c) 2006-2007, Johan Thelin
* 
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, 
* are permitted provided that the following conditions are met:
* 
*     * Redistributions of source code must retain the above copyright notice, 
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice,  
*       this list of conditions and the following disclaimer in the documentation 
*       and/or other materials provided with the distribution.
*     * Neither the name of APress nor the names of its contributors 
*       may be used to endorse or promote products derived from this software 
*       without specific prior written permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

  1. ifndef MYCLASS_H
  2. define MYCLASS_H
  3. include <QObject>
  4. include <QString>

class MyClass : public QObject {

 Q_OBJECT

public:

 MyClass( const QString &text, QObject *parent = 0 );
 const QString& text() const;
 int getLengthOfText() const;

public slots:

 void setText( const QString &text );

signals:

 void textChanged( const QString& );

private:

 QString m_text;

};

  1. endif // MYCLASS_H

Chapter01\signals-and-slots\sig-slot.cpp /*

* Copyright (c) 2006-2007, Johan Thelin
* 
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, 
* are permitted provided that the following conditions are met:
* 
*     * Redistributions of source code must retain the above copyright notice, 
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice,  
*       this list of conditions and the following disclaimer in the documentation 
*       and/or other materials provided with the distribution.
*     * Neither the name of APress nor the names of its contributors 
*       may be used to endorse or promote products derived from this software 
*       without specific prior written permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

  1. include "myclass.h"
  2. include <QtDebug>

int main( int argc, char **argv ) {

 QObject parent;
 MyClass *a, *b, *c;
 a = new MyClass( "foo", &parent );
 b = new MyClass( "bar", &parent );
 c = new MyClass( "baz", &parent );
 QObject::connect(
   a, SIGNAL(textChanged(const QString&)),
   b, SLOT(setText(const QString&)) );
 QObject::connect(
   b, SIGNAL(textChanged(const QString&)),
   c, SLOT(setText(const QString&)) );
 QObject::connect(
   c, SIGNAL(textChanged(const QString&)),
   b, SLOT(setText(const QString&)) );
 qDebug() << "--- After creation ---";
 qDebug() << "a:" << a->text() << "\nb:" << b->text() << "\nc:" << c->text();
 c->setText( "test" );
 qDebug() << "--- After test ---";
 qDebug() << "a:" << a->text() << "\nb:" << b->text() << "\nc:" << c->text();
 a->setText( "Qt" );
 qDebug() << "--- After Qt ---";
 qDebug() << "a:" << a->text() << "\nb:" << b->text() << "\nc:" << c->text();
 return a->getLengthOfText() - c->getLengthOfText();

}


 </source>


Qt signal test

<source lang="cpp">

Foundations of Qt Development\Chapter16\signaltest\main.cpp /*

* Copyright (c) 2006-2007, Johan Thelin
* 
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, 
* are permitted provided that the following conditions are met:
* 
*     * Redistributions of source code must retain the above copyright notice, 
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice,  
*       this list of conditions and the following disclaimer in the documentation 
*       and/or other materials provided with the distribution.
*     * Neither the name of APress nor the names of its contributors 
*       may be used to endorse or promote products derived from this software 
*       without specific prior written permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
  1. include <QtTest>
  2. include "spinboxtest.h"

QTEST_MAIN(SpinBoxTest)

Foundations of Qt Development\Chapter16\signaltest\spinboxtest.cpp /*

* Copyright (c) 2006-2007, Johan Thelin
* 
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, 
* are permitted provided that the following conditions are met:
* 
*     * Redistributions of source code must retain the above copyright notice, 
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice,  
*       this list of conditions and the following disclaimer in the documentation 
*       and/or other materials provided with the distribution.
*     * Neither the name of APress nor the names of its contributors 
*       may be used to endorse or promote products derived from this software 
*       without specific prior written permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
  1. include <QtTest>
  2. include <QSpinBox>
  3. include "spinboxtest.h"

Q_DECLARE_METATYPE ( Qt::Key ) void SpinBoxTest::testKeys() {

 QSpinBox spinBox;
 spinBox.setRange( 1, 10 );
 
 QFETCH( Qt::Key, key );
 QFETCH( int, startValue );
 
 spinBox.setValue( startValue );
 
 QSignalSpy spy( &spinBox, SIGNAL(valueChanged(int)) );
 
 QTest::keyClick( &spinBox, key );
 QTEST( spinBox.value(), "endValue" );
 
 QFETCH( bool, willSignal );
 if( willSignal )
 {
   QCOMPARE( spy.count(), 1 );
   QTEST( spy.takeFirst()[0].toInt(), "endValue" );
 }
 else
   QCOMPARE( spy.count(), 0 );

} void SpinBoxTest::testKeys_data() {

 QTest::addColumn<Qt::Key>( "key" );
 QTest::addColumn<int>( "startValue" );
 QTest::addColumn<int>( "endValue" );
 QTest::addColumn<bool>( "willSignal" );
   
 QTest::newRow( "Up" ) << Qt::Key_Up << 5 << 6 << true;
 QTest::newRow( "Down" ) << Qt::Key_Down << 5 << 4 << true;
 QTest::newRow( "Up, limit" ) << Qt::Key_Up << 10 << 10 << false;
 QTest::newRow( "Down, limit" ) << Qt::Key_Down << 1 << 1 << false;

} void SpinBoxTest::testClicks() {

 QSpinBox spinBox;  
 spinBox.setRange( 1, 10 );
 
 QSize size = spinBox.size();
 QPoint upButton = QPoint( size.width()-2, 2 );
 QPoint downButton = QPoint( size.width()-2, size.height()-2 );
 QFETCH( QString, direction );
 QFETCH( int, startValue );
 
 spinBox.setValue( startValue );
 QSignalSpy spy( &spinBox, SIGNAL(valueChanged(int)) );
 
 if( direction.toLower() == "up" )
   QTest::mouseClick( &spinBox, Qt::LeftButton, 0, upButton );
 else if (direction.toLower() == "down" )
   QTest::mouseClick( &spinBox, Qt::LeftButton, 0, downButton );
 else
   QWARN( "Unknown direction - no clicks issued." );
 
 QTEST( spinBox.value(), "endValue" );
 
 QFETCH( bool, willSignal );
 if( willSignal )
 {
   QCOMPARE( spy.count(), 1 );
   QTEST( spy.takeFirst()[0].toInt(), "endValue" );
 }
 else
   QCOMPARE( spy.count(), 0 );

} void SpinBoxTest::testClicks_data() {

 QTest::addColumn<QString>( "direction" );
 QTest::addColumn<int>( "startValue" );
 QTest::addColumn<int>( "endValue" );
 QTest::addColumn<bool>( "willSignal" );
   
 QTest::newRow( "Up" ) << "Up" << 5 << 6 << true;
 QTest::newRow( "Down" ) << "Down" << 5 << 4 << true;
 QTest::newRow( "Up, limit" ) << "Up" << 10 << 10 << false;
 QTest::newRow( "Down, limit" ) << "Down" << 1 << 1 << false;

} void SpinBoxTest::testSetting() {

 QSpinBox spinBox;
 spinBox.setRange( 1, 10 );
 
 QFETCH( int, startValue );
 spinBox.setValue( startValue );
 
 QSignalSpy spy( &spinBox, SIGNAL(valueChanged(int)) );  
 
 QFETCH( int, value );
 spinBox.setValue( value );
 QTEST( spinBox.value(), "endValue" );
 
 QFETCH( bool, willSignal );
 if( willSignal )
 {
   QCOMPARE( spy.count(), 1 );
   QTEST( spy.takeFirst()[0].toInt(), "endValue" );
 }
 else
   QCOMPARE( spy.count(), 0 );

} void SpinBoxTest::testSetting_data() {

 QTest::addColumn<int>( "startValue" );
 QTest::addColumn<int>( "value" );
 QTest::addColumn<int>( "endValue" );
 QTest::addColumn<bool>( "willSignal" );
   
 QTest::newRow( "Valid" ) << 1 << 5 << 5 << true;
 QTest::newRow( "Over" ) << 9 << 11 << 10 << true;
 QTest::newRow( "Under" ) << 2 << 0 << 1 << true;
 QTest::newRow( "Valid, no change" ) << 5 << 5 << 5 << false;
 QTest::newRow( "Over, no change" ) << 10 << 11 << 10 << false;
 QTest::newRow( "Under, no change" ) << 1 << 0 << 1 << false;

}

Foundations of Qt Development\Chapter16\signaltest\spinboxtest.h /*

* Copyright (c) 2006-2007, Johan Thelin
* 
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, 
* are permitted provided that the following conditions are met:
* 
*     * Redistributions of source code must retain the above copyright notice, 
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice,  
*       this list of conditions and the following disclaimer in the documentation 
*       and/or other materials provided with the distribution.
*     * Neither the name of APress nor the names of its contributors 
*       may be used to endorse or promote products derived from this software 
*       without specific prior written permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
  1. ifndef SPINBOXTEST_H
  2. define SPINBOXTEST_H
  3. include <QObject>

class SpinBoxTest : public QObject {

 Q_OBJECT

private slots:

 void testKeys();
 void testKeys_data();
 
 void testClicks();
 void testClicks_data();
 void testSetting();
 void testSetting_data();

};

  1. endif // SPINBOXTEST_H


 </source>


Quit Qt application

<source lang="cpp">

  1. include <QApplication>
  2. include <QPushButton>

int main(int argc, char *argv[]) {

   QApplication app(argc, argv);
   QPushButton *button = new QPushButton("Quit");
   QObject::connect(button, SIGNAL(clicked()),&app, SLOT(quit()));
   button->show();
   return app.exec();

}


 </source>


Widget style

<source lang="cpp"> /****************************************************************************

    • Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    • All rights reserved.
    • Contact: Nokia Corporation (qt-info@nokia.com)
    • This file is part of the examples of the Qt Toolkit.
    • $QT_BEGIN_LICENSE:LGPL$
    • Commercial Usage
    • Licensees holding valid Qt Commercial licenses may use this file in
    • accordance with the Qt Commercial License Agreement provided with the
    • Software or, alternatively, in accordance with the terms contained in
    • a written agreement between you and Nokia.
    • GNU Lesser General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU Lesser
    • General Public License version 2.1 as published by the Free Software
    • Foundation and appearing in the file LICENSE.LGPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU Lesser General Public License version 2.1 requirements
    • will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    • In addition, as a special exception, Nokia gives you certain additional
    • rights. These rights are described in the Nokia Qt LGPL Exception
    • version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    • GNU General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU
    • General Public License version 3.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 the GNU General Public License version 3.0 requirements will be
    • met: http://www.gnu.org/copyleft/gpl.html.
    • If you have questions regarding the use of this file, please contact
    • Nokia at qt-info@nokia.com.
    • $QT_END_LICENSE$
                                                                                                                                                        • /
  1. ifndef WIDGETGALLERY_H
  2. define WIDGETGALLERY_H
  3. include <QDialog>

QT_BEGIN_NAMESPACE class QCheckBox; class QComboBox; class QDateTimeEdit; class QDial; class QGroupBox; class QLabel; class QLineEdit; class QProgressBar; class QPushButton; class QRadioButton; class QScrollBar; class QSlider; class QSpinBox; class QTabWidget; class QTableWidget; class QTextEdit; QT_END_NAMESPACE

class WidgetGallery : public QDialog {

   Q_OBJECT

public:

   WidgetGallery(QWidget *parent = 0);

private slots:

   void changeStyle(const QString &styleName);
   void changePalette();
   void advanceProgressBar();

private:

   void createTopLeftGroupBox();
   void createTopRightGroupBox();
   void createBottomLeftTabWidget();
   void createBottomRightGroupBox();
   void createProgressBar();
   QPalette originalPalette;

   QLabel *styleLabel;
   QComboBox *styleComboBox;
   QCheckBox *useStylePaletteCheckBox;
   QCheckBox *disableWidgetsCheckBox;
   QGroupBox *topLeftGroupBox;
   QRadioButton *radioButton1;
   QRadioButton *radioButton2;
   QRadioButton *radioButton3;
   QCheckBox *checkBox;
   QGroupBox *topRightGroupBox;
   QPushButton *defaultPushButton;
   QPushButton *togglePushButton;
   QPushButton *flatPushButton;
   QTabWidget *bottomLeftTabWidget;
   QTableWidget *tableWidget;
   QTextEdit *textEdit;
   QGroupBox *bottomRightGroupBox;
   QLineEdit *lineEdit;
   QSpinBox *spinBox;
   QDateTimeEdit *dateTimeEdit;
   QSlider *slider;
   QScrollBar *scrollBar;
   QDial *dial;
   QProgressBar *progressBar;

};

  1. endif


  1. include <QtGui>
  2. include "norwegianwoodstyle.h"
  3. include "widgetgallery.h"

WidgetGallery::WidgetGallery(QWidget *parent)

   : QDialog(parent)

{

   originalPalette = QApplication::palette();
   styleComboBox = new QComboBox;
   styleComboBox->addItem("NorwegianWood");
   styleComboBox->addItems(QStyleFactory::keys());
   styleLabel = new QLabel(tr("&Style:"));
   styleLabel->setBuddy(styleComboBox);
   useStylePaletteCheckBox = new QCheckBox(tr("&Use style"s standard palette"));
   useStylePaletteCheckBox->setChecked(true);
   disableWidgetsCheckBox = new QCheckBox(tr("&Disable widgets"));
   createTopLeftGroupBox();
   createTopRightGroupBox();
   createBottomLeftTabWidget();
   createBottomRightGroupBox();
   createProgressBar();
   connect(styleComboBox, SIGNAL(activated(const QString &)),

           this, SLOT(changeStyle(const QString &)));
   connect(useStylePaletteCheckBox, SIGNAL(toggled(bool)),
           this, SLOT(changePalette()));
   connect(disableWidgetsCheckBox, SIGNAL(toggled(bool)),
           topLeftGroupBox, SLOT(setDisabled(bool)));
   connect(disableWidgetsCheckBox, SIGNAL(toggled(bool)),
           topRightGroupBox, SLOT(setDisabled(bool)));
   connect(disableWidgetsCheckBox, SIGNAL(toggled(bool)),
           bottomLeftTabWidget, SLOT(setDisabled(bool)));
   connect(disableWidgetsCheckBox, SIGNAL(toggled(bool)),
           bottomRightGroupBox, SLOT(setDisabled(bool)));
   QHBoxLayout *topLayout = new QHBoxLayout;

   topLayout->addWidget(styleLabel);
   topLayout->addWidget(styleComboBox);
   topLayout->addStretch(1);
   topLayout->addWidget(useStylePaletteCheckBox);
   topLayout->addWidget(disableWidgetsCheckBox);
   QGridLayout *mainLayout = new QGridLayout;
   mainLayout->addLayout(topLayout, 0, 0, 1, 2);
   mainLayout->addWidget(topLeftGroupBox, 1, 0);
   mainLayout->addWidget(topRightGroupBox, 1, 1);
   mainLayout->addWidget(bottomLeftTabWidget, 2, 0);
   mainLayout->addWidget(bottomRightGroupBox, 2, 1);
   mainLayout->addWidget(progressBar, 3, 0, 1, 2);
   mainLayout->setRowStretch(1, 1);
   mainLayout->setRowStretch(2, 1);
   mainLayout->setColumnStretch(0, 1);
   mainLayout->setColumnStretch(1, 1);
   setLayout(mainLayout);
   setWindowTitle(tr("Styles"));
   changeStyle("NorwegianWood");

}

void WidgetGallery::changeStyle(const QString &styleName)

{

   if (styleName == "NorwegianWood") {
       QApplication::setStyle(new NorwegianWoodStyle);
   } else {
       QApplication::setStyle(QStyleFactory::create(styleName));
   }
   changePalette();

}

void WidgetGallery::changePalette()

{

   if (useStylePaletteCheckBox->isChecked())
       QApplication::setPalette(QApplication::style()->standardPalette());
   else
       QApplication::setPalette(originalPalette);

}

void WidgetGallery::advanceProgressBar()

{

   int curVal = progressBar->value();
   int maxVal = progressBar->maximum();
   progressBar->setValue(curVal + (maxVal - curVal) / 100);

}

void WidgetGallery::createTopLeftGroupBox()

{

   topLeftGroupBox = new QGroupBox(tr("Group 1"));
   radioButton1 = new QRadioButton(tr("Radio button 1"));
   radioButton2 = new QRadioButton(tr("Radio button 2"));
   radioButton3 = new QRadioButton(tr("Radio button 3"));
   radioButton1->setChecked(true);
   checkBox = new QCheckBox(tr("Tri-state check box"));
   checkBox->setTristate(true);
   checkBox->setCheckState(Qt::PartiallyChecked);
   QVBoxLayout *layout = new QVBoxLayout;
   layout->addWidget(radioButton1);
   layout->addWidget(radioButton2);
   layout->addWidget(radioButton3);
   layout->addWidget(checkBox);
   layout->addStretch(1);
   topLeftGroupBox->setLayout(layout);

}

void WidgetGallery::createTopRightGroupBox() {

   topRightGroupBox = new QGroupBox(tr("Group 2"));
   defaultPushButton = new QPushButton(tr("Default Push Button"));
   defaultPushButton->setDefault(true);
   togglePushButton = new QPushButton(tr("Toggle Push Button"));
   togglePushButton->setCheckable(true);
   togglePushButton->setChecked(true);
   flatPushButton = new QPushButton(tr("Flat Push Button"));
   flatPushButton->setFlat(true);
   QVBoxLayout *layout = new QVBoxLayout;
   layout->addWidget(defaultPushButton);
   layout->addWidget(togglePushButton);
   layout->addWidget(flatPushButton);
   layout->addStretch(1);
   topRightGroupBox->setLayout(layout);

} void WidgetGallery::createBottomLeftTabWidget() {

   bottomLeftTabWidget = new QTabWidget;
   bottomLeftTabWidget->setSizePolicy(QSizePolicy::Preferred,
                                      QSizePolicy::Ignored);
   QWidget *tab1 = new QWidget;
   tableWidget = new QTableWidget(10, 10);
   QHBoxLayout *tab1hbox = new QHBoxLayout;
   tab1hbox->setMargin(5);
   tab1hbox->addWidget(tableWidget);
   tab1->setLayout(tab1hbox);
   QWidget *tab2 = new QWidget;
   textEdit = new QTextEdit;
   textEdit->setPlainText(tr("Twinkle, twinkle, little star,\n"
                             "How I wonder what you are.\n"
                             "Up above the world so high,\n"
                             "Like a diamond in the sky.\n"
                             "Twinkle, twinkle, little star,\n"
                             "How I wonder what you are!\n"));
                    
   QHBoxLayout *tab2hbox = new QHBoxLayout;
   tab2hbox->setMargin(5);
   tab2hbox->addWidget(textEdit);
   tab2->setLayout(tab2hbox);
   bottomLeftTabWidget->addTab(tab1, tr("&Table"));
   bottomLeftTabWidget->addTab(tab2, tr("Text &Edit"));

} void WidgetGallery::createBottomRightGroupBox() {

   bottomRightGroupBox = new QGroupBox(tr("Group 3"));
   bottomRightGroupBox->setCheckable(true);
   bottomRightGroupBox->setChecked(true);
   lineEdit = new QLineEdit("s3cRe7");
   lineEdit->setEchoMode(QLineEdit::Password);
   spinBox = new QSpinBox(bottomRightGroupBox);
   spinBox->setValue(50);
   dateTimeEdit = new QDateTimeEdit(bottomRightGroupBox);
   dateTimeEdit->setDateTime(QDateTime::currentDateTime());
   slider = new QSlider(Qt::Horizontal, bottomRightGroupBox);
   slider->setValue(40);
   scrollBar = new QScrollBar(Qt::Horizontal, bottomRightGroupBox);
   scrollBar->setValue(60);
   dial = new QDial(bottomRightGroupBox);
   dial->setValue(30);
   dial->setNotchesVisible(true);
   QGridLayout *layout = new QGridLayout;
   layout->addWidget(lineEdit, 0, 0, 1, 2);
   layout->addWidget(spinBox, 1, 0, 1, 2);
   layout->addWidget(dateTimeEdit, 2, 0, 1, 2);
   layout->addWidget(slider, 3, 0);
   layout->addWidget(scrollBar, 4, 0);
   layout->addWidget(dial, 3, 1, 2, 1);
   layout->setRowStretch(5, 1);
   bottomRightGroupBox->setLayout(layout);

}

void WidgetGallery::createProgressBar() {

   progressBar = new QProgressBar;
   progressBar->setRange(0, 10000);
   progressBar->setValue(0);
   QTimer *timer = new QTimer(this);
   connect(timer, SIGNAL(timeout()), this, SLOT(advanceProgressBar()));
   timer->start(1000);

}


  1. ifndef NORWEGIANWOODSTYLE_H
  2. define NORWEGIANWOODSTYLE_H
  3. include <QMotifStyle>
  4. include <QPalette>

QT_BEGIN_NAMESPACE class QPainterPath; QT_END_NAMESPACE

class NorwegianWoodStyle : public QMotifStyle {

   Q_OBJECT

public:

   NorwegianWoodStyle() {}
   void polish(QPalette &palette);
   void polish(QWidget *widget);
   void unpolish(QWidget *widget);
   int pixelMetric(PixelMetric metric, const QStyleOption *option,
                   const QWidget *widget) const;
   int styleHint(StyleHint hint, const QStyleOption *option,
                 const QWidget *widget, QStyleHintReturn *returnData) const;
   void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
                      QPainter *painter, const QWidget *widget) const;
   void drawControl(ControlElement control, const QStyleOption *option,
                    QPainter *painter, const QWidget *widget) const;

private:

   static void setTexture(QPalette &palette, QPalette::ColorRole role,
                          const QPixmap &pixmap);
   static QPainterPath roundRectPath(const QRect &rect);

};

  1. endif


  1. include <QtGui>
  2. include "norwegianwoodstyle.h"

void NorwegianWoodStyle::polish(QPalette &palette) {

   QColor brown(212, 140, 95);
   QColor beige(236, 182, 120);
   QColor slightlyOpaqueBlack(0, 0, 0, 63);
   QPixmap backgroundImage(":/images/woodbackground.png");
   QPixmap buttonImage(":/images/woodbutton.png");
   QPixmap midImage = buttonImage;
   QPainter painter;
   painter.begin(&midImage);
   painter.setPen(Qt::NoPen);
   painter.fillRect(midImage.rect(), slightlyOpaqueBlack);
   painter.end();
   palette = QPalette(brown);
   palette.setBrush(QPalette::BrightText, Qt::white);
   palette.setBrush(QPalette::Base, beige);
   palette.setBrush(QPalette::Highlight, Qt::darkGreen);
   setTexture(palette, QPalette::Button, buttonImage);
   setTexture(palette, QPalette::Mid, midImage);
   setTexture(palette, QPalette::Window, backgroundImage);
   QBrush brush = palette.background();
   brush.setColor(brush.color().dark());
   palette.setBrush(QPalette::Disabled, QPalette::WindowText, brush);
   palette.setBrush(QPalette::Disabled, QPalette::Text, brush);
   palette.setBrush(QPalette::Disabled, QPalette::ButtonText, brush);
   palette.setBrush(QPalette::Disabled, QPalette::Base, brush);
   palette.setBrush(QPalette::Disabled, QPalette::Button, brush);
   palette.setBrush(QPalette::Disabled, QPalette::Mid, brush);

}

void NorwegianWoodStyle::polish(QWidget *widget)

{

   if (qobject_cast<QPushButton *>(widget)
           || qobject_cast<QComboBox *>(widget))
       widget->setAttribute(Qt::WA_Hover, true);

}

void NorwegianWoodStyle::unpolish(QWidget *widget)

{

   if (qobject_cast<QPushButton *>(widget)
           || qobject_cast<QComboBox *>(widget))
       widget->setAttribute(Qt::WA_Hover, false);

}

int NorwegianWoodStyle::pixelMetric(PixelMetric metric,

                                   const QStyleOption *option,
                                   const QWidget *widget) const

{

   switch (metric) {
   case PM_ComboBoxFrameWidth:
       return 8;
   case PM_ScrollBarExtent:
       return QMotifStyle::pixelMetric(metric, option, widget) + 4;
   default:
       return QMotifStyle::pixelMetric(metric, option, widget);
   }

}

int NorwegianWoodStyle::styleHint(StyleHint hint, const QStyleOption *option,

                                 const QWidget *widget,
                                 QStyleHintReturn *returnData) const

{

   switch (hint) {
   case SH_DitherDisabledText:
       return int(false);
   case SH_EtchDisabledText:
       return int(true);
   default:
       return QMotifStyle::styleHint(hint, option, widget, returnData);
   }

}

void NorwegianWoodStyle::drawPrimitive(PrimitiveElement element,

                                      const QStyleOption *option,
                                      QPainter *painter,
                                      const QWidget *widget) const

{

   switch (element) {
   case PE_PanelButtonCommand:
       {
           int delta = (option->state & State_MouseOver) ? 64 : 0;
           QColor slightlyOpaqueBlack(0, 0, 0, 63);
           QColor semiTransparentWhite(255, 255, 255, 127 + delta);
           QColor semiTransparentBlack(0, 0, 0, 127 - delta);
           int x, y, width, height;
           option->rect.getRect(&x, &y, &width, &height);
           QPainterPath roundRect = roundRectPath(option->rect);

           int radius = qMin(width, height) / 2;
           QBrush brush;

           bool darker;
           const QStyleOptionButton *buttonOption =
                   qstyleoption_cast<const QStyleOptionButton *>(option);
           if (buttonOption
                   && (buttonOption->features & QStyleOptionButton::Flat)) {
               brush = option->palette.background();
               darker = (option->state & (State_Sunken | State_On));
           } else {
               if (option->state & (State_Sunken | State_On)) {
                   brush = option->palette.mid();
                   darker = !(option->state & State_Sunken);
               } else {
                   brush = option->palette.button();
                   darker = false;

               }

           }
           painter->save();

           painter->setRenderHint(QPainter::Antialiasing, true);

           painter->fillPath(roundRect, brush);

           if (darker)

               painter->fillPath(roundRect, slightlyOpaqueBlack);
           int penWidth;

           if (radius < 10)
               penWidth = 3;
           else if (radius < 20)
               penWidth = 5;
           else
               penWidth = 7;
           QPen topPen(semiTransparentWhite, penWidth);
           QPen bottomPen(semiTransparentBlack, penWidth);
           if (option->state & (State_Sunken | State_On))
               qSwap(topPen, bottomPen);
           int x1 = x;
           int x2 = x + radius;
           int x3 = x + width - radius;
           int x4 = x + width;
           if (option->direction == Qt::RightToLeft) {
               qSwap(x1, x4);
               qSwap(x2, x3);
           }
           QPolygon topHalf;
           topHalf << QPoint(x1, y)
                   << QPoint(x4, y)
                   << QPoint(x3, y + radius)
                   << QPoint(x2, y + height - radius)
                   << QPoint(x1, y + height);
           painter->setClipPath(roundRect);
           painter->setClipRegion(topHalf, Qt::IntersectClip);
           painter->setPen(topPen);
           painter->drawPath(roundRect);

           QPolygon bottomHalf = topHalf;
           bottomHalf[0] = QPoint(x4, y + height);
           painter->setClipPath(roundRect);
           painter->setClipRegion(bottomHalf, Qt::IntersectClip);
           painter->setPen(bottomPen);
           painter->drawPath(roundRect);
           painter->setPen(option->palette.foreground().color());
           painter->setClipping(false);
           painter->drawPath(roundRect);
           painter->restore();
       }
       break;

   default:

       QMotifStyle::drawPrimitive(element, option, painter, widget);
   }

}

void NorwegianWoodStyle::drawControl(ControlElement element,

                                    const QStyleOption *option,
                                    QPainter *painter,
                                    const QWidget *widget) const

{

   switch (element) {
   case CE_PushButtonLabel:
       {
           QStyleOptionButton myButtonOption;
           const QStyleOptionButton *buttonOption =
                   qstyleoption_cast<const QStyleOptionButton *>(option);
           if (buttonOption) {
               myButtonOption = *buttonOption;
               if (myButtonOption.palette.currentColorGroup()
                       != QPalette::Disabled) {
                   if (myButtonOption.state & (State_Sunken | State_On)) {
                       myButtonOption.palette.setBrush(QPalette::ButtonText,
                               myButtonOption.palette.brightText());
                   }
               }
           }
           QMotifStyle::drawControl(element, &myButtonOption, painter, widget);
       }
       break;
   default:
       QMotifStyle::drawControl(element, option, painter, widget);
   }

}

void NorwegianWoodStyle::setTexture(QPalette &palette, QPalette::ColorRole role,

                                   const QPixmap &pixmap)

{

   for (int i = 0; i < QPalette::NColorGroups; ++i) {
       QColor color = palette.brush(QPalette::ColorGroup(i), role).color();
       palette.setBrush(QPalette::ColorGroup(i), role, QBrush(color, pixmap));
   }

}

QPainterPath NorwegianWoodStyle::roundRectPath(const QRect &rect)

{

   int radius = qMin(rect.width(), rect.height()) / 2;
   int diam = 2 * radius;
   int x1, y1, x2, y2;
   rect.getCoords(&x1, &y1, &x2, &y2);
   QPainterPath path;
   path.moveTo(x2, y1 + radius);
   path.arcTo(QRect(x2 - diam, y1, diam, diam), 0.0, +90.0);
   path.lineTo(x1 + radius, y1);
   path.arcTo(QRect(x1, y1, diam, diam), 90.0, +90.0);
   path.lineTo(x1, y2 - radius);
   path.arcTo(QRect(x1, y2 - diam, diam, diam), 180.0, +90.0);
   path.lineTo(x1 + radius, y2);
   path.arcTo(QRect(x2 - diam, y2 - diam, diam, diam), 270.0, +90.0);
   path.closeSubpath();
   return path;

}


  1. include <QApplication>
  2. include "widgetgallery.h"

int main(int argc, char *argv[]) {

   Q_INIT_RESOURCE(styles);
   QApplication app(argc, argv);
   WidgetGallery gallery;
   gallery.show();
   return app.exec();

}


 </source>