C++/Qt/Signal

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

A Slot Responds to a Signal

  
#include <QApplication>
#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();
}


event filters

  
/****************************************************************************
**
** 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$
**
****************************************************************************/
#ifndef FILTEROBJECT_H
#define FILTEROBJECT_H
#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;
};
#endif




#include <QtGui>
#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);
}




#include <QApplication>
#include <QTextEdit>
#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();
}


Inherited slot

  
/****************************************************************************
**
** 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$
**
****************************************************************************/
#ifndef WINDOW_H
#define WINDOW_H
#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]
#endif



#include <QDebug>
#include "button.h"
Button::Button(QWidget *parent)
    : QPushButton(parent)
{
}
void Button::animateClick()
{
    qDebug() << "Extra code goes here...";
    QPushButton::animateClick();
}


#include <QApplication>
#include <QDebug>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QMetaMethod>
#include <QWidget>
#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();
}


Mark method with Q_INVOKABLE

  
/****************************************************************************
**
** 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$
**
****************************************************************************/
#ifndef WINDOW_H
#define WINDOW_H
#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]
#endif


#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();
}


#include <QApplication>
#include <QDebug>
#include "window.h"
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Window window;
    qDebug() << window.metaObject()->methodCount();
    window.show();
    return app.exec();
}


Multi-event handlers

  
#include <QApplication>
#include <QVBoxLayout>
#include <QLabel>
#include <QSpinBox>
#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();
}


QSignal mapper

  

/****************************************************************************
**
** 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$
**
****************************************************************************/
#ifndef BUTTONWIDGET_H
#define BUTTONWIDGET_H
#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;
 
};

#endif


#include <QtGui>
#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);
}



#include <QMainWindow>
#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));
    }
};


#include <QApplication>
#include "buttonwidget.h"
#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();
}


Qt signals and slots

  
/*
 * 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.
 *
 */
 
#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.
 *
 */
 
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
#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;
};
#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.
 *
 */
 
#include "myclass.h"
#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();
}


Qt signal test

  

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.
 *
 */
#include <QtTest>
#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.
 *
 */
#include <QtTest>
#include <QSpinBox>
#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.
 *
 */
#ifndef SPINBOXTEST_H
#define SPINBOXTEST_H
#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();
};
#endif // SPINBOXTEST_H


Quit Qt application

  
#include <QApplication>
#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();
}


Widget style

  
/****************************************************************************
**
** 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$
**
****************************************************************************/
#ifndef WIDGETGALLERY_H
#define WIDGETGALLERY_H
#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;
};

#endif



#include <QtGui>
#include "norwegianwoodstyle.h"
#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);
}



#ifndef NORWEGIANWOODSTYLE_H
#define NORWEGIANWOODSTYLE_H
#include <QMotifStyle>
#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);
};

#endif



#include <QtGui>
#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;
}



#include <QApplication>
#include "widgetgallery.h"
int main(int argc, char *argv[])
{
    Q_INIT_RESOURCE(styles);
    QApplication app(argc, argv);
    WidgetGallery gallery;
    gallery.show();
    return app.exec();
}