38be0d1383
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
1682 lines
56 KiB
C++
1682 lines
56 KiB
C++
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
|
** All rights reserved.
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
**
|
|
** This file is part of the test suite of the Qt Toolkit.
|
|
**
|
|
** $QT_BEGIN_LICENSE:LGPL$
|
|
** No Commercial Usage
|
|
** This file contains pre-release code and may not be distributed.
|
|
** You may use this file in accordance with the terms and conditions
|
|
** contained in the Technology Preview License Agreement accompanying
|
|
** this package.
|
|
**
|
|
** 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.
|
|
**
|
|
** If you have questions regarding the use of this file, please contact
|
|
** Nokia at qt-info@nokia.com.
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
#include <QtCore>
|
|
#include <QtGui>
|
|
#include <QtTest/QtTest>
|
|
#include <QtDebug>
|
|
#include <QMetaObject>
|
|
#ifdef QT3_SUPPORT
|
|
#include <Q3ProgressBar>
|
|
#endif
|
|
|
|
#include <private/qstylesheetstyle_p.h>
|
|
#include "../platformquirks.h"
|
|
|
|
//TESTED_CLASS=
|
|
//TESTED_FILES=
|
|
|
|
class tst_QStyleSheetStyle : public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
tst_QStyleSheetStyle();
|
|
~tst_QStyleSheetStyle();
|
|
|
|
private slots:
|
|
void repolish();
|
|
void numinstances();
|
|
void widgetsBeforeAppStyleSheet();
|
|
void widgetsAfterAppStyleSheet();
|
|
void applicationStyleSheet();
|
|
void windowStyleSheet();
|
|
void widgetStyleSheet();
|
|
void reparentWithNoChildStyleSheet();
|
|
void reparentWithChildStyleSheet();
|
|
void dynamicProperty();
|
|
// NB! Invoking this slot after layoutSpacing crashes on Mac.
|
|
void namespaces();
|
|
#ifdef Q_OS_MAC
|
|
void layoutSpacing();
|
|
#endif
|
|
void qproperty();
|
|
void palettePropagation();
|
|
void fontPropagation();
|
|
void onWidgetDestroyed();
|
|
void fontPrecedence();
|
|
void focusColors();
|
|
void hoverColors();
|
|
void background();
|
|
void tabAlignement();
|
|
void attributesList();
|
|
void minmaxSizes();
|
|
void task206238_twice();
|
|
void transparent();
|
|
void proxyStyle();
|
|
void dialogButtonBox();
|
|
void emptyStyleSheet();
|
|
void toolTip();
|
|
void embeddedFonts();
|
|
void opaquePaintEvent_data();
|
|
void opaquePaintEvent();
|
|
void complexWidgetFocus();
|
|
void task188195_baseBackground();
|
|
void task232085_spinBoxLineEditBg();
|
|
void changeStyleInChangeEvent();
|
|
void QTBUG15910_crashNullWidget();
|
|
|
|
//at the end because it mess with the style.
|
|
void widgetStyle();
|
|
void appStyle();
|
|
void QTBUG11658_cachecrash();
|
|
private:
|
|
QColor COLOR(const QWidget& w) {
|
|
w.ensurePolished();
|
|
return w.palette().color(w.foregroundRole());
|
|
}
|
|
QColor APPCOLOR(const QWidget& w) {
|
|
w.ensurePolished();
|
|
return qApp->palette(&w).color(w.foregroundRole());
|
|
}
|
|
QColor BACKGROUND(const QWidget& w) {
|
|
w.ensurePolished();
|
|
return w.palette().color(w.backgroundRole());
|
|
}
|
|
QColor APPBACKGROUND(const QWidget& w) {
|
|
w.ensurePolished();
|
|
return qApp->palette(&w).color(w.backgroundRole());
|
|
}
|
|
int FONTSIZE(const QWidget &w) {
|
|
w.ensurePolished();
|
|
return w.font().pointSize();
|
|
}
|
|
int APPFONTSIZE(const QWidget &w) {
|
|
return qApp->font(&w).pointSize();
|
|
}
|
|
};
|
|
|
|
tst_QStyleSheetStyle::tst_QStyleSheetStyle()
|
|
{
|
|
}
|
|
|
|
tst_QStyleSheetStyle::~tst_QStyleSheetStyle()
|
|
{
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::numinstances()
|
|
{
|
|
QWidget w;
|
|
QCommonStyle *style = new QCommonStyle;
|
|
style->setParent(&w);
|
|
QWidget c(&w);
|
|
w.show();
|
|
|
|
// set and unset application stylesheet
|
|
QCOMPARE(QStyleSheetStyle::numinstances, 0);
|
|
qApp->setStyleSheet("* { color: red; }");
|
|
QCOMPARE(QStyleSheetStyle::numinstances, 1);
|
|
qApp->setStyleSheet("");
|
|
QCOMPARE(QStyleSheetStyle::numinstances, 0);
|
|
|
|
// set and unset application stylesheet+widget
|
|
qApp->setStyleSheet("* { color: red; }");
|
|
w.setStyleSheet("color: red;");
|
|
QCOMPARE(QStyleSheetStyle::numinstances, 2);
|
|
w.setStyle(style);
|
|
QCOMPARE(QStyleSheetStyle::numinstances, 2);
|
|
qApp->setStyleSheet("");
|
|
QCOMPARE(QStyleSheetStyle::numinstances, 1);
|
|
w.setStyleSheet("");
|
|
QCOMPARE(QStyleSheetStyle::numinstances, 0);
|
|
|
|
// set and unset widget stylesheet
|
|
w.setStyle(0);
|
|
w.setStyleSheet("color: red");
|
|
QCOMPARE(QStyleSheetStyle::numinstances, 1);
|
|
c.setStyle(style);
|
|
QCOMPARE(QStyleSheetStyle::numinstances, 2);
|
|
w.setStyleSheet("");
|
|
QCOMPARE(QStyleSheetStyle::numinstances, 0);
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::widgetsBeforeAppStyleSheet()
|
|
{
|
|
QPushButton w1; // widget with no stylesheet
|
|
qApp->setStyleSheet("* { color: red; }");
|
|
QVERIFY(COLOR(w1) == QColor("red"));
|
|
w1.setStyleSheet("color: white");
|
|
QVERIFY(COLOR(w1) == QColor("white"));
|
|
qApp->setStyleSheet("");
|
|
QVERIFY(COLOR(w1) == QColor("white"));
|
|
w1.setStyleSheet("");
|
|
QVERIFY(COLOR(w1) == APPCOLOR(w1));
|
|
}
|
|
|
|
class FriendlySpinBox : public QSpinBox { friend class tst_QStyleSheetStyle; };
|
|
|
|
void tst_QStyleSheetStyle::widgetsAfterAppStyleSheet()
|
|
{
|
|
qApp->setStyleSheet("* { color: red; font-size: 32pt; }");
|
|
QPushButton w1;
|
|
FriendlySpinBox spin;
|
|
QVERIFY(COLOR(w1) == QColor("red"));
|
|
QVERIFY(COLOR(spin) == QColor("red"));
|
|
QVERIFY(COLOR(*spin.lineEdit()) == QColor("red"));
|
|
QCOMPARE(FONTSIZE(w1), 32);
|
|
QCOMPARE(FONTSIZE(spin), 32);
|
|
QCOMPARE(FONTSIZE(*spin.lineEdit()), 32);
|
|
w1.setStyleSheet("color: white");
|
|
QVERIFY(COLOR(w1) == QColor("white"));
|
|
QVERIFY(COLOR(spin) == QColor("red"));
|
|
QVERIFY(COLOR(*spin.lineEdit()) == QColor("red"));
|
|
w1.setStyleSheet("");
|
|
QVERIFY(COLOR(w1) == QColor("red"));
|
|
QVERIFY(COLOR(spin) == QColor("red"));
|
|
QVERIFY(COLOR(*spin.lineEdit()) == QColor("red"));
|
|
w1.setStyleSheet("color: white");
|
|
QVERIFY(COLOR(w1) == QColor("white"));
|
|
qApp->setStyleSheet("");
|
|
QVERIFY(COLOR(w1) == QColor("white"));
|
|
QVERIFY(COLOR(spin) == APPCOLOR(spin));
|
|
QVERIFY(COLOR(*spin.lineEdit()) == APPCOLOR(*spin.lineEdit()));
|
|
w1.setStyleSheet("");
|
|
QVERIFY(COLOR(w1) == APPCOLOR(w1));
|
|
// QCOMPARE(FONTSIZE(w1), APPFONTSIZE(w1)); //### task 244261
|
|
QCOMPARE(FONTSIZE(spin), APPFONTSIZE(spin));
|
|
//QCOMPARE(FONTSIZE(*spin.lineEdit()), APPFONTSIZE(*spin.lineEdit())); //### task 244261
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::applicationStyleSheet()
|
|
{
|
|
QPushButton w1;
|
|
qApp->setStyleSheet("* { color: red; }");
|
|
QVERIFY(COLOR(w1) == QColor("red"));
|
|
qApp->setStyleSheet("* { color: white; }");
|
|
QVERIFY(COLOR(w1) == QColor("white"));
|
|
qApp->setStyleSheet("");
|
|
QVERIFY(COLOR(w1) == APPCOLOR(w1));
|
|
qApp->setStyleSheet("* { color: red }");
|
|
QVERIFY(COLOR(w1) == QColor("red"));
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::windowStyleSheet()
|
|
{
|
|
QPushButton w1;
|
|
qApp->setStyleSheet("");
|
|
w1.setStyleSheet("* { color: red; }");
|
|
QVERIFY(COLOR(w1) == QColor("red"));
|
|
w1.setStyleSheet("* { color: white; }");
|
|
QVERIFY(COLOR(w1) == QColor("white"));
|
|
w1.setStyleSheet("");
|
|
QVERIFY(COLOR(w1) == APPCOLOR(w1));
|
|
w1.setStyleSheet("* { color: red }");
|
|
QVERIFY(COLOR(w1) == QColor("red"));
|
|
|
|
qApp->setStyleSheet("* { color: green }");
|
|
QVERIFY(COLOR(w1) == QColor("red"));
|
|
w1.setStyleSheet("");
|
|
QVERIFY(COLOR(w1) == QColor("green"));
|
|
qApp->setStyleSheet("");
|
|
QVERIFY(COLOR(w1) == APPCOLOR(w1));
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::widgetStyleSheet()
|
|
{
|
|
QPushButton w1;
|
|
QPushButton *pb = new QPushButton(&w1);
|
|
QPushButton &w2 = *pb;
|
|
|
|
qApp->setStyleSheet("");
|
|
w1.setStyleSheet("* { color: red }");
|
|
QVERIFY(COLOR(w1) == QColor("red"));
|
|
QVERIFY(COLOR(w2) == QColor("red"));
|
|
|
|
w2.setStyleSheet("* { color: white }");
|
|
QVERIFY(COLOR(w2) == QColor("white"));
|
|
|
|
w1.setStyleSheet("* { color: blue }");
|
|
QVERIFY(COLOR(w1) == QColor("blue"));
|
|
QVERIFY(COLOR(w2) == QColor("white"));
|
|
|
|
w1.setStyleSheet("");
|
|
QVERIFY(COLOR(w1) == APPCOLOR(w1));
|
|
QVERIFY(COLOR(w2) == QColor("white"));
|
|
|
|
w2.setStyleSheet("");
|
|
QVERIFY(COLOR(w1) == APPCOLOR(w1));
|
|
QVERIFY(COLOR(w2) == APPCOLOR(w2));
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::reparentWithNoChildStyleSheet()
|
|
{
|
|
QPushButton p1, p2;
|
|
QPushButton *pb = new QPushButton(&p1);
|
|
QPushButton &c1 = *pb; // child with no stylesheet
|
|
|
|
qApp->setStyleSheet("");
|
|
p1.setStyleSheet("* { color: red }");
|
|
QVERIFY(COLOR(c1) == QColor("red"));
|
|
c1.setParent(&p2);
|
|
QVERIFY(COLOR(c1) == APPCOLOR(c1));
|
|
|
|
p2.setStyleSheet("* { color: white }");
|
|
QVERIFY(COLOR(c1) == QColor("white"));
|
|
|
|
c1.setParent(&p1);
|
|
QVERIFY(COLOR(c1) == QColor("red"));
|
|
|
|
qApp->setStyleSheet("* { color: blue }");
|
|
c1.setParent(0);
|
|
QVERIFY(COLOR(c1) == QColor("blue"));
|
|
delete pb;
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::reparentWithChildStyleSheet()
|
|
{
|
|
qApp->setStyleSheet("");
|
|
QPushButton p1, p2;
|
|
QPushButton *pb = new QPushButton(&p1);
|
|
QPushButton &c1 = *pb;
|
|
|
|
c1.setStyleSheet("background: gray");
|
|
QVERIFY(BACKGROUND(c1) == QColor("gray"));
|
|
c1.setParent(&p2);
|
|
QVERIFY(BACKGROUND(c1) == QColor("gray"));
|
|
|
|
qApp->setStyleSheet("* { color: white }");
|
|
c1.setParent(&p1);
|
|
QVERIFY(BACKGROUND(c1) == QColor("gray"));
|
|
QVERIFY(COLOR(c1) == QColor("white"));
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::repolish()
|
|
{
|
|
qApp->setStyleSheet("");
|
|
QPushButton p1;
|
|
p1.setStyleSheet("color: red; background: white");
|
|
QVERIFY(BACKGROUND(p1) == QColor("white"));
|
|
p1.setStyleSheet("background: white");
|
|
QVERIFY(COLOR(p1) == APPCOLOR(p1));
|
|
p1.setStyleSheet("color: red");
|
|
QVERIFY(COLOR(p1) == QColor("red"));
|
|
QVERIFY(BACKGROUND(p1) == APPBACKGROUND(p1));
|
|
p1.setStyleSheet("");
|
|
QVERIFY(COLOR(p1) == APPCOLOR(p1));
|
|
QVERIFY(BACKGROUND(p1) == APPBACKGROUND(p1));
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::widgetStyle()
|
|
{
|
|
qApp->setStyleSheet("");
|
|
|
|
QWidget *window1 = new QWidget;
|
|
window1->setObjectName("window1");
|
|
QWidget *widget1 = new QWidget(window1);
|
|
widget1->setObjectName("widget1");
|
|
QWidget *widget2 = new QWidget;
|
|
widget2->setObjectName("widget2");
|
|
QWidget *window2 = new QWidget;
|
|
window2->setObjectName("window2");
|
|
window1->ensurePolished();
|
|
window2->ensurePolished();
|
|
widget1->ensurePolished();
|
|
widget2->ensurePolished();
|
|
|
|
QWindowsStyle style1, style2;
|
|
QPointer<QStyle> pstyle1 = &style1;
|
|
QPointer<QStyle> pstyle2 = &style2;
|
|
|
|
QStyle *appStyle = qApp->style();
|
|
|
|
// Sanity: By default, a window inherits the application style
|
|
QCOMPARE(appStyle, window1->style());
|
|
|
|
// Setting a custom style on a widget
|
|
window1->setStyle(&style1);
|
|
QCOMPARE(static_cast<QStyle *>(&style1), window1->style());
|
|
|
|
// Setting another style must not delete the older style
|
|
window1->setStyle(&style2);
|
|
QCOMPARE(static_cast<QStyle *>(&style2), window1->style());
|
|
QVERIFY(!pstyle1.isNull()); // case we have not already crashed
|
|
|
|
// Setting null style must make it follow the qApp style
|
|
window1->setStyle(0);
|
|
QCOMPARE(window1->style(), appStyle);
|
|
QVERIFY(!pstyle2.isNull()); // case we have not already crashed
|
|
QVERIFY(!pstyle2.isNull()); // case we have not already crashed
|
|
|
|
// Sanity: Set the stylesheet
|
|
window1->setStyleSheet(":x { }");
|
|
|
|
QPointer<QStyleSheetStyle> proxy = (QStyleSheetStyle *)window1->style();
|
|
QVERIFY(!proxy.isNull());
|
|
QCOMPARE(proxy->metaObject()->className(), "QStyleSheetStyle"); // must be our proxy
|
|
QVERIFY(proxy->base == 0); // and follows the application
|
|
|
|
// Set the stylesheet
|
|
window1->setStyle(&style1);
|
|
QVERIFY(proxy.isNull()); // we create a new one each time
|
|
proxy = (QStyleSheetStyle *)window1->style();
|
|
QCOMPARE(proxy->metaObject()->className(), "QStyleSheetStyle"); // it is a proxy
|
|
QCOMPARE(proxy->baseStyle(), static_cast<QStyle *>(&style1)); // must have been replaced with the new one
|
|
|
|
// Update the stylesheet and check nothing changes
|
|
window1->setStyleSheet(":y { }");
|
|
QCOMPARE(window1->style()->metaObject()->className(), "QStyleSheetStyle"); // it is a proxy
|
|
QCOMPARE(proxy->baseStyle(), static_cast<QStyle *>(&style1)); // the same guy
|
|
|
|
// Remove the stylesheet
|
|
proxy = (QStyleSheetStyle *)window1->style();
|
|
window1->setStyleSheet("");
|
|
QVERIFY(proxy.isNull()); // should have disappeared
|
|
QCOMPARE(window1->style(), static_cast<QStyle *>(&style1)); // its restored
|
|
|
|
// Style Sheet existing children propagation
|
|
window1->setStyleSheet(":z { }");
|
|
proxy = (QStyleSheetStyle *)window1->style();
|
|
QCOMPARE(proxy->metaObject()->className(), "QStyleSheetStyle");
|
|
QCOMPARE(window1->style(), widget1->style()); // proxy must have propagated
|
|
QCOMPARE(widget2->style(), appStyle); // widget2 is following the app style
|
|
|
|
// Style Sheet automatic propagation to new children
|
|
widget2->setParent(window1); // reparent in!
|
|
QCOMPARE(window1->style(), widget2->style()); // proxy must have propagated
|
|
|
|
// Style Sheet automatic removal from children who abandoned their parents
|
|
window2->setStyle(&style2);
|
|
widget2->setParent(window2); // reparent
|
|
QCOMPARE(widget2->style(), appStyle); // widget2 is following the app style
|
|
|
|
// Style Sheet propagation on a child widget with a custom style
|
|
widget2->setStyle(&style1);
|
|
window2->setStyleSheet(":x { }");
|
|
proxy = (QStyleSheetStyle *)widget2->style();
|
|
QCOMPARE(proxy->metaObject()->className(), "QStyleSheetStyle");
|
|
QCOMPARE(proxy->baseStyle(), static_cast<QStyle *>(&style1));
|
|
|
|
// Style Sheet propagation on a child widget with a custom style already set
|
|
window2->setStyleSheet("");
|
|
QCOMPARE(window2->style(), static_cast<QStyle *>(&style2));
|
|
QCOMPARE(widget2->style(), static_cast<QStyle *>(&style1));
|
|
widget2->setStyle(0);
|
|
window2->setStyleSheet(":x { }");
|
|
widget2->setStyle(&style1);
|
|
proxy = (QStyleSheetStyle *)widget2->style();
|
|
QCOMPARE(proxy->metaObject()->className(), "QStyleSheetStyle");
|
|
|
|
// QApplication, QWidget both having a style sheet
|
|
|
|
// clean everything out
|
|
window1->setStyle(0);
|
|
window1->setStyleSheet("");
|
|
window2->setStyle(0);
|
|
window2->setStyleSheet("");
|
|
qApp->setStyle(0);
|
|
|
|
qApp->setStyleSheet("may_insanity_prevail { }"); // app has styleshet
|
|
QCOMPARE(window1->style(), qApp->style());
|
|
QCOMPARE(window1->style()->metaObject()->className(), "QStyleSheetStyle");
|
|
QCOMPARE(widget1->style()->metaObject()->className(), "QStyleSheetStyle"); // check the child
|
|
window1->setStyleSheet("may_more_insanity_prevail { }"); // window has stylesheet
|
|
QCOMPARE(window1->style()->metaObject()->className(), "QStyleSheetStyle"); // a new one
|
|
QCOMPARE(widget1->style(), window1->style()); // child follows...
|
|
proxy = (QStyleSheetStyle *) window1->style();
|
|
QWindowsStyle *newStyle = new QWindowsStyle;
|
|
qApp->setStyle(newStyle); // set a custom style on app
|
|
proxy = (QStyleSheetStyle *) window1->style();
|
|
QCOMPARE(proxy->baseStyle(), static_cast<QStyle *>(newStyle)); // magic ;) the widget still follows the application
|
|
QCOMPARE(static_cast<QStyle *>(proxy), widget1->style()); // child still follows...
|
|
|
|
window1->setStyleSheet(""); // remove stylesheet
|
|
QCOMPARE(window1->style(), qApp->style()); // is this cool or what
|
|
QCOMPARE(widget1->style(), qApp->style()); // annoying child follows...
|
|
QWindowsStyle wndStyle;
|
|
window1->setStyle(&wndStyle);
|
|
QCOMPARE(window1->style()->metaObject()->className(), "QStyleSheetStyle"); // auto wraps it
|
|
QCOMPARE(widget1->style(), window1->style()); // and auto propagates to child
|
|
qApp->setStyleSheet(""); // remove the app stylesheet
|
|
QCOMPARE(window1->style(), static_cast<QStyle *>(&wndStyle)); // auto dewrap
|
|
QCOMPARE(widget1->style(), qApp->style()); // and child state is restored
|
|
window1->setStyle(0); // let sanity prevail
|
|
qApp->setStyle(0);
|
|
|
|
delete window1;
|
|
delete widget2;
|
|
delete window2;
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::appStyle()
|
|
{
|
|
qApp->setStyleSheet("");
|
|
// qApp style can never be 0
|
|
QVERIFY(QApplication::style() != 0);
|
|
QPointer<QStyle> style1 = new QWindowsStyle;
|
|
QPointer<QStyle> style2 = new QWindowsStyle;
|
|
qApp->setStyle(style1);
|
|
// Basic sanity
|
|
QVERIFY(qApp->style() == style1);
|
|
qApp->setStyle(style2);
|
|
QVERIFY(style1.isNull()); // qApp must have taken ownership and deleted it
|
|
// Setting null should not crash
|
|
qApp->setStyle(0);
|
|
QVERIFY(qApp->style() == style2);
|
|
|
|
// Set the stylesheet
|
|
qApp->setStyleSheet("whatever");
|
|
QPointer<QStyleSheetStyle> sss = (QStyleSheetStyle *)qApp->style();
|
|
QVERIFY(!sss.isNull());
|
|
QCOMPARE(sss->metaObject()->className(), "QStyleSheetStyle"); // must be our proxy now
|
|
QVERIFY(!style2.isNull()); // this should exist as it is the base of the proxy
|
|
QVERIFY(sss->baseStyle() == style2);
|
|
style1 = new QWindowsStyle;
|
|
qApp->setStyle(style1);
|
|
QVERIFY(style2.isNull()); // should disappear automatically
|
|
QVERIFY(sss.isNull()); // should disappear automatically
|
|
|
|
// Update the stylesheet and check nothing changes
|
|
sss = (QStyleSheetStyle *)qApp->style();
|
|
qApp->setStyleSheet("whatever2");
|
|
QVERIFY(qApp->style() == sss);
|
|
QVERIFY(sss->baseStyle() == style1);
|
|
|
|
// Revert the stylesheet
|
|
qApp->setStyleSheet("");
|
|
QVERIFY(sss.isNull()); // should have disappeared
|
|
QVERIFY(qApp->style() == style1);
|
|
|
|
qApp->setStyleSheet("");
|
|
QVERIFY(qApp->style() == style1);
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::dynamicProperty()
|
|
{
|
|
qApp->setStyleSheet(QString());
|
|
|
|
QString appStyle = qApp->style()->metaObject()->className();
|
|
QPushButton pb1, pb2;
|
|
pb1.setProperty("type", "critical");
|
|
qApp->setStyleSheet("*[class~=\"QPushButton\"] { color: red; } *[type=\"critical\"] { background: white; }");
|
|
QVERIFY(COLOR(pb1) == Qt::red);
|
|
QVERIFY(BACKGROUND(pb1) == Qt::white);
|
|
|
|
pb2.setProperty("class", "critical"); // dynamic class
|
|
pb2.setStyleSheet(QLatin1String(".critical[style~=\"") + appStyle + "\"] { color: blue }");
|
|
pb2.show();
|
|
|
|
QVERIFY(COLOR(pb2) == Qt::blue);
|
|
}
|
|
|
|
#ifdef Q_OS_MAC
|
|
#include <QtGui/QMacStyle>
|
|
void tst_QStyleSheetStyle::layoutSpacing()
|
|
{
|
|
qApp->setStyleSheet("* { color: red }");
|
|
QCheckBox ck1;
|
|
QCheckBox ck2;
|
|
QWidget window;
|
|
int spacing_widgetstyle = window.style()->layoutSpacing(ck1.sizePolicy().controlType(), ck2.sizePolicy().controlType(), Qt::Vertical);
|
|
int spacing_style = window.style()->layoutSpacing(ck1.sizePolicy().controlType(), ck2.sizePolicy().controlType(), Qt::Vertical);
|
|
QCOMPARE(spacing_widgetstyle, spacing_style);
|
|
}
|
|
#endif
|
|
|
|
void tst_QStyleSheetStyle::qproperty()
|
|
{
|
|
QPushButton pb;
|
|
pb.setStyleSheet("QPushButton { qproperty-text: hello; qproperty-checkable: true; qproperty-checked: 1}");
|
|
pb.ensurePolished();
|
|
QCOMPARE(pb.text(), QString("hello"));
|
|
QCOMPARE(pb.isCheckable(), true);
|
|
QCOMPARE(pb.isChecked(), true);
|
|
}
|
|
|
|
namespace ns {
|
|
class PushButton1 : public QPushButton {
|
|
Q_OBJECT
|
|
public:
|
|
PushButton1() { }
|
|
};
|
|
class PushButton2 : public PushButton1 {
|
|
Q_OBJECT
|
|
public:
|
|
PushButton2() { setProperty("class", "PushButtonTwo PushButtonDuo"); }
|
|
};
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::namespaces()
|
|
{
|
|
ns::PushButton1 pb1;
|
|
qApp->setStyleSheet("ns--PushButton1 { background: white }");
|
|
QVERIFY(BACKGROUND(pb1) == QColor("white"));
|
|
qApp->setStyleSheet(".ns--PushButton1 { background: red }");
|
|
QVERIFY(BACKGROUND(pb1) == QColor("red"));
|
|
|
|
ns::PushButton2 pb2;
|
|
qApp->setStyleSheet("ns--PushButton1 { background: blue}");
|
|
QVERIFY(BACKGROUND(pb2) == QColor("blue"));
|
|
qApp->setStyleSheet("ns--PushButton2 { background: magenta }");
|
|
QVERIFY(BACKGROUND(pb2) == QColor("magenta"));
|
|
qApp->setStyleSheet(".PushButtonTwo { background: white; }");
|
|
QVERIFY(BACKGROUND(pb2) == QColor("white"));
|
|
qApp->setStyleSheet(".PushButtonDuo { background: red; }");
|
|
QVERIFY(BACKGROUND(pb2) == QColor("red"));
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::palettePropagation()
|
|
{
|
|
qApp->setStyleSheet("");
|
|
QGroupBox gb;
|
|
QPushButton *push = new QPushButton(&gb);
|
|
QPushButton &pb = *push;
|
|
push->setText("AsdF");
|
|
|
|
gb.setStyleSheet("QGroupBox { color: red }");
|
|
QVERIFY(COLOR(gb) == Qt::red);
|
|
QVERIFY(COLOR(pb) == APPCOLOR(pb)); // palette shouldn't propagate
|
|
gb.setStyleSheet("QGroupBox * { color: red }");
|
|
|
|
QVERIFY(COLOR(pb) == Qt::red);
|
|
QVERIFY(COLOR(gb) == APPCOLOR(gb));
|
|
|
|
QWidget window;
|
|
window.setStyleSheet("* { color: white; }");
|
|
pb.setParent(&window);
|
|
QVERIFY(COLOR(pb) == Qt::white);
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::fontPropagation()
|
|
{
|
|
qApp->setStyleSheet("");
|
|
QComboBox cb;
|
|
cb.addItem("item1");
|
|
cb.addItem("item2");
|
|
|
|
QAbstractItemView *popup = cb.view();
|
|
int viewFontSize = FONTSIZE(*popup);
|
|
|
|
cb.setStyleSheet("QComboBox { font-size: 20pt; }");
|
|
QVERIFY(FONTSIZE(cb) == 20);
|
|
QVERIFY(FONTSIZE(*popup) == viewFontSize);
|
|
QGroupBox gb;
|
|
QPushButton *push = new QPushButton(&gb);
|
|
QPushButton &pb = *push;
|
|
int buttonFontSize = FONTSIZE(pb);
|
|
int gbFontSize = FONTSIZE(gb);
|
|
|
|
gb.setStyleSheet("QGroupBox { font-size: 20pt }");
|
|
QVERIFY(FONTSIZE(gb) == 20);
|
|
QVERIFY(FONTSIZE(pb) == buttonFontSize); // font does not propagate
|
|
gb.setStyleSheet("QGroupBox * { font-size: 20pt; }");
|
|
QVERIFY(FONTSIZE(gb) == gbFontSize);
|
|
QVERIFY(FONTSIZE(pb) == 20);
|
|
|
|
QWidget window;
|
|
window.setStyleSheet("* { font-size: 10pt }");
|
|
pb.setParent(&window);
|
|
QCOMPARE(FONTSIZE(pb), 10);
|
|
window.setStyleSheet("");
|
|
QVERIFY(FONTSIZE(pb) == buttonFontSize);
|
|
|
|
QTabWidget tw;
|
|
tw.setStyleSheet("QTabWidget { font-size: 20pt; }");
|
|
QVERIFY(FONTSIZE(tw) == 20);
|
|
QWidget *child = qFindChild<QWidget *>(&tw, "qt_tabwidget_tabbar");
|
|
QVERIFY2(child, "QTabWidget did not contain a widget named \"qt_tabwidget_tabbar\"");
|
|
QVERIFY(FONTSIZE(*child) == 20);
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::onWidgetDestroyed()
|
|
{
|
|
qApp->setStyleSheet("");
|
|
QLabel *l = new QLabel;
|
|
l->setStyleSheet("QLabel { color: red }");
|
|
QPointer<QStyleSheetStyle> ss = (QStyleSheetStyle *) l->style();
|
|
delete l;
|
|
QVERIFY(ss.isNull());
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::fontPrecedence()
|
|
{
|
|
QLineEdit edit;
|
|
edit.show();
|
|
QFont font;
|
|
QVERIFY(FONTSIZE(edit) != 22); // Sanity check to make sure this test makes sense.
|
|
edit.setStyleSheet("QLineEdit { font-size: 22pt; }");
|
|
QCOMPARE(FONTSIZE(edit), 22);
|
|
font.setPointSize(16);
|
|
edit.setFont(font);
|
|
QCOMPARE(FONTSIZE(edit), 22);
|
|
edit.setStyleSheet("");
|
|
QCOMPARE(FONTSIZE(edit), 16);
|
|
font.setPointSize(18);
|
|
edit.setFont(font);
|
|
QCOMPARE(FONTSIZE(edit), 18);
|
|
edit.setStyleSheet("QLineEdit { font-size: 20pt; }");
|
|
QCOMPARE(FONTSIZE(edit), 20);
|
|
edit.setStyleSheet("");
|
|
QCOMPARE(FONTSIZE(edit), 18);
|
|
edit.hide();
|
|
|
|
QLineEdit edit2;
|
|
edit2.setReadOnly(true);
|
|
edit2.setStyleSheet("QLineEdit { font-size: 24pt; } QLineEdit:read-only { font-size: 26pt; }");
|
|
QCOMPARE(FONTSIZE(edit2), 26);
|
|
}
|
|
|
|
// Ensure primary will only return true if the color covers more than 50% of pixels
|
|
static bool testForColors(const QImage& image, const QColor& color, bool ensurePrimary=false)
|
|
{
|
|
int count = 0;
|
|
QRgb rgb = color.rgba();
|
|
int totalCount = image.height()*image.width();
|
|
for (int y = 0; y < image.height(); ++y) {
|
|
for (int x = 0; x < image.width(); ++x) {
|
|
// Because of antialiasing we allow a certain range of errors here.
|
|
QRgb pixel = image.pixel(x, y);
|
|
|
|
if (qAbs((int)(pixel & 0xff) - (int)(rgb & 0xff)) +
|
|
qAbs((int)((pixel & 0xff00) >> 8) - (int)((rgb & 0xff00) >> 8)) +
|
|
qAbs((int)((pixel & 0xff0000) >> 16) - (int)((rgb & 0xff0000) >> 16)) <= 50) {
|
|
count++;
|
|
if (!ensurePrimary && count >=10 )
|
|
return true;
|
|
else if (count > totalCount/2)
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::focusColors()
|
|
{
|
|
// Tests if colors can be changed by altering the focus of the widget.
|
|
// To avoid messy pixel-by-pixel comparison, we assume that the goal
|
|
// is reached if at least ten pixels of the right color can be found in
|
|
// the image.
|
|
// For this reason, we use unusual and extremely ugly colors! :-)
|
|
|
|
#if !defined(Q_OS_WIN32) && !defined(Q_OS_MAC) && !(defined(Q_OS_LINUX) && defined(Q_CC_GNU) \
|
|
&& !defined(Q_CC_INTEL))
|
|
QSKIP("This is a fragile test which fails on many esoteric platforms "
|
|
"because of focus problems. "
|
|
"That doesn't mean that the feature doesn't work in practice.", SkipAll);
|
|
#endif
|
|
/* Disabled changing style in order not to mess with the application style
|
|
#ifdef Q_OS_MAC
|
|
int styleCount = 3;
|
|
QStyle *styles[3];
|
|
#else
|
|
int styleCount = 2;
|
|
QStyle *styles[2];
|
|
#endif
|
|
|
|
styles[0] = new QPlastiqueStyle;
|
|
styles[1] = new QWindowsStyle;
|
|
|
|
#ifdef Q_OS_MAC
|
|
styles[2] = new QMacStyle;
|
|
#endif
|
|
|
|
|
|
for (int i = 0; i < styleCount; ++i) {
|
|
qApp->setStyle(styles[i]);
|
|
*/
|
|
QList<QWidget *> widgets;
|
|
widgets << new QPushButton("TESTING");
|
|
widgets << new QLineEdit("TESTING");
|
|
widgets << new QLabel("TESTING");
|
|
QSpinBox *spinbox = new QSpinBox;
|
|
spinbox->setValue(8888);
|
|
widgets << spinbox;
|
|
QComboBox *combobox = new QComboBox;
|
|
combobox->setEditable(true);
|
|
combobox->addItems(QStringList() << "TESTING");
|
|
widgets << combobox;
|
|
widgets << new QLabel("TESTING");
|
|
|
|
#ifdef Q_WS_QWS
|
|
// QWS has its own special focus logic which is slightly different
|
|
// and I don't dare change it at this point, because someone will
|
|
// be relying on it. It means that setFocus() on a NoFocus widget (i.e.
|
|
// a QLabel) will not work before the window is activated.
|
|
widgets[2]->setFocusPolicy(Qt::StrongFocus);
|
|
#endif
|
|
|
|
foreach (QWidget *widget, widgets) {
|
|
QDialog frame;
|
|
QLayout* layout = new QGridLayout;
|
|
|
|
QLineEdit* dummy = new QLineEdit; // Avoids initial focus.
|
|
|
|
widget->setStyleSheet("*:focus { border:none; background: #e8ff66; color: #ff0084 }");
|
|
|
|
layout->addWidget(dummy);
|
|
layout->addWidget(widget);
|
|
frame.setLayout(layout);
|
|
|
|
frame.show();
|
|
#ifdef Q_WS_X11
|
|
qt_x11_wait_for_window_manager(&frame);
|
|
#endif
|
|
QApplication::setActiveWindow(&frame);
|
|
widget->setFocus();
|
|
QApplication::processEvents();
|
|
|
|
QImage image(frame.width(), frame.height(), QImage::Format_ARGB32);
|
|
frame.render(&image);
|
|
if (image.depth() < 24) {
|
|
QSKIP("Test doesn't support color depth < 24", SkipAll);
|
|
}
|
|
|
|
QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)),
|
|
(QString::fromLatin1(widget->metaObject()->className())
|
|
+ " did not contain background color #e8ff66, using style "
|
|
+ QString::fromLatin1(qApp->style()->metaObject()->className()))
|
|
.toLocal8Bit().constData());
|
|
QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)),
|
|
(QString::fromLatin1(widget->metaObject()->className())
|
|
+ " did not contain text color #ff0084, using style "
|
|
+ QString::fromLatin1(qApp->style()->metaObject()->className()))
|
|
.toLocal8Bit().constData());
|
|
}
|
|
// }
|
|
}
|
|
|
|
|
|
void tst_QStyleSheetStyle::hoverColors()
|
|
{
|
|
if (!PlatformQuirks::haveMouseCursor())
|
|
QSKIP("No mouse Cursor on this platform",SkipAll);
|
|
QList<QWidget *> widgets;
|
|
widgets << new QPushButton("TESTING");
|
|
widgets << new QLineEdit("TESTING");
|
|
widgets << new QLabel("TESTING");
|
|
QSpinBox *spinbox = new QSpinBox;
|
|
spinbox->setValue(8888);
|
|
widgets << spinbox;
|
|
QComboBox *combobox = new QComboBox;
|
|
combobox->setEditable(true);
|
|
combobox->addItems(QStringList() << "TESTING");
|
|
widgets << combobox;
|
|
widgets << new QLabel("<b>TESTING</b>");
|
|
|
|
foreach (QWidget *widget, widgets) {
|
|
//without Qt::X11BypassWindowManagerHint the window manager may move the window after we moved the cursor
|
|
QDialog frame(0, Qt::X11BypassWindowManagerHint);
|
|
QLayout* layout = new QGridLayout;
|
|
|
|
QLineEdit* dummy = new QLineEdit;
|
|
|
|
widget->setStyleSheet("*:hover { border:none; background: #e8ff66; color: #ff0084 }");
|
|
|
|
layout->addWidget(dummy);
|
|
layout->addWidget(widget);
|
|
frame.setLayout(layout);
|
|
|
|
frame.show();
|
|
#ifdef Q_WS_QWS
|
|
//QWS does not implement enter/leave when windows are shown underneath the cursor
|
|
QCursor::setPos(QPoint(0,0));
|
|
#endif
|
|
|
|
#ifdef Q_WS_X11
|
|
qt_x11_wait_for_window_manager(&frame);
|
|
#endif
|
|
QApplication::setActiveWindow(&frame);
|
|
QTest::qWait(60);
|
|
//move the mouse inside the widget, it should be colored
|
|
QTest::mouseMove ( widget, QPoint(5,5));
|
|
QTest::qWait(60);
|
|
|
|
QVERIFY(widget->testAttribute(Qt::WA_UnderMouse));
|
|
|
|
QImage image(frame.width(), frame.height(), QImage::Format_ARGB32);
|
|
frame.render(&image);
|
|
|
|
QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)),
|
|
(QString::fromLatin1(widget->metaObject()->className())
|
|
+ " did not contain background color #e8ff66").toLocal8Bit().constData());
|
|
QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)),
|
|
(QString::fromLatin1(widget->metaObject()->className())
|
|
+ " did not contain text color #ff0084").toLocal8Bit().constData());
|
|
|
|
//move the mouse outside the widget, it should NOT be colored
|
|
QTest::mouseMove ( dummy, QPoint(5,5));
|
|
QTest::qWait(60);
|
|
|
|
frame.render(&image);
|
|
|
|
QVERIFY2(!testForColors(image, QColor(0xe8, 0xff, 0x66)),
|
|
(QString::fromLatin1(widget->metaObject()->className())
|
|
+ " did contain background color #e8ff66").toLocal8Bit().constData());
|
|
QVERIFY2(!testForColors(image, QColor(0xff, 0x00, 0x84)),
|
|
(QString::fromLatin1(widget->metaObject()->className())
|
|
+ " did contain text color #ff0084").toLocal8Bit().constData());
|
|
|
|
//move the mouse again inside the widget, it should be colored
|
|
QTest::mouseMove (widget, QPoint(5,5));
|
|
QTest::qWait(60);
|
|
|
|
QVERIFY(widget->testAttribute(Qt::WA_UnderMouse));
|
|
|
|
frame.render(&image);
|
|
|
|
QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)),
|
|
(QString::fromLatin1(widget->metaObject()->className())
|
|
+ " did not contain background color #e8ff66").toLocal8Bit().constData());
|
|
QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)),
|
|
(QString::fromLatin1(widget->metaObject()->className())
|
|
+ " did not contain text color #ff0084").toLocal8Bit().constData());
|
|
}
|
|
|
|
}
|
|
|
|
class SingleInheritanceDialog : public QDialog
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
SingleInheritanceDialog(QWidget *w = 0) :
|
|
QDialog(w)
|
|
{
|
|
}
|
|
};
|
|
|
|
class DoubleInheritanceDialog : public SingleInheritanceDialog
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
DoubleInheritanceDialog(QWidget *w = 0) :
|
|
SingleInheritanceDialog(w)
|
|
{
|
|
}
|
|
};
|
|
|
|
void tst_QStyleSheetStyle::background()
|
|
{
|
|
const int number = 4;
|
|
QWidget* widgets[number];
|
|
// Testing inheritance styling of QDialog.
|
|
widgets[0] = new SingleInheritanceDialog;
|
|
widgets[0]->setStyleSheet("* { background-color: #e8ff66; }");
|
|
widgets[1] = new DoubleInheritanceDialog;
|
|
widgets[1]->setStyleSheet("* { background-color: #e8ff66; }");
|
|
|
|
// Testing gradients in QComboBox.
|
|
QLayout* layout;
|
|
QComboBox* cb;
|
|
// First color
|
|
widgets[2] = new QDialog;
|
|
layout = new QGridLayout;
|
|
cb = new QComboBox;
|
|
cb->setStyleSheet("* { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop:0 #e8ff66, stop:1 #000000); }");
|
|
layout->addWidget(cb);
|
|
widgets[2]->setLayout(layout);
|
|
// Second color
|
|
widgets[3] = new QDialog;
|
|
layout = new QGridLayout;
|
|
cb = new QComboBox;
|
|
cb->setStyleSheet("* { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop:0 #e8ff66, stop:1 #000000); }");
|
|
layout->addWidget(cb);
|
|
widgets[3]->setLayout(layout);
|
|
|
|
for (int c = 0; c < number; ++c) {
|
|
QWidget* widget = widgets[c];
|
|
|
|
widget->show();
|
|
#ifdef Q_WS_X11
|
|
qt_x11_wait_for_window_manager(widget);
|
|
#endif
|
|
|
|
QImage image(widget->width(), widget->height(), QImage::Format_ARGB32);
|
|
widget->render(&image);
|
|
if (image.depth() < 24) {
|
|
QSKIP("Test doesn't support color depth < 24", SkipAll);
|
|
}
|
|
|
|
QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)),
|
|
(QString::fromLatin1(widget->metaObject()->className())
|
|
+ " did not contain background image with color #e8ff66")
|
|
.toLocal8Bit().constData());
|
|
|
|
delete widget;
|
|
}
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::tabAlignement()
|
|
{
|
|
QWidget topLevel;
|
|
QTabWidget tabWidget(&topLevel);
|
|
tabWidget.addTab(new QLabel("tab1"),"tab1");
|
|
tabWidget.resize(QSize(400,400));
|
|
topLevel.show();
|
|
QTest::qWaitForWindowShown(&tabWidget);
|
|
QTest::qWait(50);
|
|
QTabBar *bar = qFindChild<QTabBar*>(&tabWidget);
|
|
QVERIFY(bar);
|
|
//check the tab is on the right
|
|
tabWidget.setStyleSheet("QTabWidget::tab-bar { alignment: right ; }");
|
|
qApp->processEvents();
|
|
QVERIFY(bar->geometry().right() > 380);
|
|
QVERIFY(bar->geometry().left() > 200);
|
|
//check the tab is on the middle
|
|
tabWidget.setStyleSheet("QTabWidget::tab-bar { alignment: center ; }");
|
|
QVERIFY(bar->geometry().right() < 300);
|
|
QVERIFY(bar->geometry().left() > 100);
|
|
//check the tab is on the left
|
|
tabWidget.setStyleSheet("QTabWidget::tab-bar { alignment: left ; }");
|
|
QVERIFY(bar->geometry().left() < 20);
|
|
QVERIFY(bar->geometry().right() < 200);
|
|
|
|
tabWidget.setTabPosition(QTabWidget::West);
|
|
//check the tab is on the top
|
|
QVERIFY(bar->geometry().top() < 20);
|
|
QVERIFY(bar->geometry().bottom() < 200);
|
|
//check the tab is on the bottom
|
|
tabWidget.setStyleSheet("QTabWidget::tab-bar { alignment: right ; }");
|
|
QVERIFY(bar->geometry().bottom() > 380);
|
|
QVERIFY(bar->geometry().top() > 200);
|
|
//check the tab is on the middle
|
|
tabWidget.setStyleSheet("QTabWidget::tab-bar { alignment: center ; }");
|
|
QVERIFY(bar->geometry().bottom() < 300);
|
|
QVERIFY(bar->geometry().top() > 100);
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::attributesList()
|
|
{
|
|
QWidget w;
|
|
QPushButton *p1=new QPushButton(&w);
|
|
QPushButton *p2=new QPushButton(&w);
|
|
QPushButton *p3=new QPushButton(&w);
|
|
QPushButton *p4=new QPushButton(&w);
|
|
p1->setProperty("prop", QStringList() << "red");
|
|
p2->setProperty("prop", QStringList() << "foo" << "red");
|
|
p3->setProperty("prop", QStringList() << "foo" << "bar");
|
|
|
|
w.setStyleSheet(" QPushButton{ background-color:blue; } QPushButton[prop~=red] { background-color:red; }");
|
|
QCOMPARE(BACKGROUND(*p1) , QColor("red"));
|
|
QCOMPARE(BACKGROUND(*p2) , QColor("red"));
|
|
QCOMPARE(BACKGROUND(*p3) , QColor("blue"));
|
|
QCOMPARE(BACKGROUND(*p4) , QColor("blue"));
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::minmaxSizes()
|
|
{
|
|
QTabWidget tabWidget;
|
|
tabWidget.setObjectName("tabWidget");
|
|
int index1 = tabWidget.addTab(new QLabel("Tab1"),"a");
|
|
|
|
QWidget *page2=new QLabel("page2");
|
|
page2->setObjectName("page2");
|
|
page2->setStyleSheet("* {background-color: white; min-width: 250px; max-width:500px }");
|
|
tabWidget.addTab(page2,"Tab2");
|
|
QWidget *page3=new QLabel("plop");
|
|
page3->setObjectName("Page3");
|
|
page3->setStyleSheet("* {background-color: yellow; min-height: 250px; max-height:500px }");
|
|
int index3 = tabWidget.addTab(page3,"very_long_long_long_long_caption");
|
|
|
|
tabWidget.setStyleSheet("QTabBar::tab { min-width:100px; max-width:130px; }");
|
|
|
|
tabWidget.show();
|
|
QTest::qWait(50);
|
|
//i allow 4px additional border from the native style (hence the -2, <=2)
|
|
QVERIFY(qAbs(page2->maximumSize().width() - 500 - 2) <= 2);
|
|
QVERIFY(qAbs(page2->minimumSize().width() - 250 - 2) <= 2);
|
|
QVERIFY(qAbs(page3->maximumSize().height() - 500 - 2) <= 2);
|
|
QVERIFY(qAbs(page3->minimumSize().height() - 250 - 2) <= 2);
|
|
QVERIFY(qAbs(page3->minimumSize().height() - 250 - 2) <= 2);
|
|
QTabBar *bar = qFindChild<QTabBar*>(&tabWidget);
|
|
QVERIFY(bar);
|
|
QVERIFY(qAbs(bar->tabRect(index1).width() - 100 - 2) <= 2);
|
|
QVERIFY(qAbs(bar->tabRect(index3).width() - 130 - 2) <= 2);
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::task206238_twice()
|
|
{
|
|
QMainWindow w;
|
|
QTabWidget* tw = new QTabWidget;
|
|
tw->addTab(new QLabel("foo"), "test");
|
|
w.setCentralWidget(tw);
|
|
w.setStyleSheet("background: red;");
|
|
w.show();
|
|
QTest::qWait(20);
|
|
QCOMPARE(BACKGROUND(w) , QColor("red"));
|
|
QCOMPARE(BACKGROUND(*tw), QColor("red"));
|
|
w.setStyleSheet("background: red;");
|
|
QTest::qWait(20);
|
|
QCOMPARE(BACKGROUND(w) , QColor("red"));
|
|
QCOMPARE(BACKGROUND(*tw), QColor("red"));
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::transparent()
|
|
{
|
|
QWidget w;
|
|
QPushButton *p1=new QPushButton(&w);
|
|
QPushButton *p2=new QPushButton(&w);
|
|
QPushButton *p3=new QPushButton(&w);
|
|
p1->setStyleSheet("background:transparent");
|
|
p2->setStyleSheet("background-color:transparent");
|
|
p3->setStyleSheet("background:rgb(0,0,0,0)");
|
|
QCOMPARE(BACKGROUND(*p1) , QColor(0,0,0,0));
|
|
QCOMPARE(BACKGROUND(*p2) , QColor(0,0,0,0));
|
|
QCOMPARE(BACKGROUND(*p3) , QColor(0,0,0,0));
|
|
}
|
|
|
|
|
|
|
|
class ProxyStyle : public QStyle
|
|
{
|
|
public:
|
|
ProxyStyle(QStyle *s)
|
|
{
|
|
style = s;
|
|
}
|
|
|
|
void drawControl(ControlElement ce, const QStyleOption *opt,
|
|
QPainter *painter, const QWidget *widget = 0) const;
|
|
|
|
void drawPrimitive(QStyle::PrimitiveElement pe,
|
|
const QStyleOption* opt,
|
|
QPainter* p ,
|
|
const QWidget* w) const
|
|
{
|
|
style->drawPrimitive(pe, opt, p, w);
|
|
}
|
|
|
|
QRect subElementRect(QStyle::SubElement se,
|
|
const QStyleOption* opt,
|
|
const QWidget* w) const
|
|
{
|
|
Q_UNUSED(se);
|
|
Q_UNUSED(opt);
|
|
Q_UNUSED(w);
|
|
return QRect(0, 0, 3, 3);
|
|
}
|
|
|
|
void drawComplexControl(QStyle::ComplexControl cc,
|
|
const QStyleOptionComplex* opt,
|
|
QPainter* p,
|
|
const QWidget* w) const
|
|
{
|
|
style->drawComplexControl(cc, opt, p, w);
|
|
}
|
|
|
|
|
|
SubControl hitTestComplexControl(QStyle::ComplexControl cc,
|
|
const QStyleOptionComplex* opt,
|
|
const QPoint& pt,
|
|
const QWidget* w) const
|
|
{
|
|
return style->hitTestComplexControl(cc, opt, pt, w);
|
|
}
|
|
|
|
QRect subControlRect(QStyle::ComplexControl cc,
|
|
const QStyleOptionComplex* opt,
|
|
QStyle::SubControl sc,
|
|
const QWidget* w) const
|
|
{
|
|
return style->subControlRect(cc, opt, sc, w);
|
|
}
|
|
|
|
int pixelMetric(QStyle::PixelMetric pm,
|
|
const QStyleOption* opt,
|
|
const QWidget* w) const
|
|
{
|
|
return style->pixelMetric(pm, opt, w);
|
|
}
|
|
|
|
|
|
QSize sizeFromContents(QStyle::ContentsType ct,
|
|
const QStyleOption* opt,
|
|
const QSize& size,
|
|
const QWidget* w) const
|
|
{
|
|
return style->sizeFromContents(ct, opt, size, w);
|
|
}
|
|
|
|
int styleHint(QStyle::StyleHint sh,
|
|
const QStyleOption* opt,
|
|
const QWidget* w,
|
|
QStyleHintReturn* shr) const
|
|
{
|
|
return style->styleHint(sh, opt, w, shr);
|
|
}
|
|
|
|
QPixmap standardPixmap(QStyle::StandardPixmap spix,
|
|
const QStyleOption* opt,
|
|
const QWidget* w) const
|
|
{
|
|
return style->standardPixmap(spix, opt, w);
|
|
}
|
|
|
|
QPixmap generatedIconPixmap(QIcon::Mode mode,
|
|
const QPixmap& pix,
|
|
const QStyleOption* opt) const
|
|
{
|
|
return style->generatedIconPixmap(mode, pix, opt);
|
|
}
|
|
|
|
private:
|
|
QStyle *style;
|
|
};
|
|
|
|
void ProxyStyle::drawControl(ControlElement ce, const QStyleOption *opt,
|
|
QPainter *painter, const QWidget *widget) const
|
|
{
|
|
if(ce == CE_PushButton)
|
|
{
|
|
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt))
|
|
{
|
|
QRect r = btn->rect;
|
|
painter->fillRect(r, Qt::green);
|
|
|
|
if(btn->state & QStyle::State_HasFocus)
|
|
painter->fillRect(r.adjusted(5, 5, -5, -5), Qt::yellow);
|
|
|
|
|
|
painter->drawText(r, Qt::AlignCenter, btn->text);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
style->drawControl(ce, opt, painter, widget);
|
|
}
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::proxyStyle()
|
|
{
|
|
//Should not crash; task 158984
|
|
|
|
ProxyStyle *proxy = new ProxyStyle(qApp->style());
|
|
QString styleSheet("QPushButton {background-color: red; }");
|
|
|
|
QWidget *w = new QWidget;
|
|
QVBoxLayout *layout = new QVBoxLayout(w);
|
|
|
|
QPushButton *pb1 = new QPushButton(qApp->style()->objectName(), w);
|
|
layout->addWidget(pb1);
|
|
|
|
QPushButton *pb2 = new QPushButton("ProxyStyle", w);
|
|
pb2->setStyle(proxy);
|
|
layout->addWidget(pb2);
|
|
|
|
QPushButton *pb3 = new QPushButton("StyleSheet", w);
|
|
pb3->setStyleSheet(styleSheet);
|
|
layout->addWidget(pb3);
|
|
|
|
QPushButton *pb4 = new QPushButton("StyleSheet then ProxyStyle ", w);
|
|
pb4->setStyleSheet(styleSheet);
|
|
|
|
// We are creating our Proxy based on current style...
|
|
// In this case it would be the QStyleSheetStyle that is deleted
|
|
// later on. We need to get access to the "real" QStyle to be able to
|
|
// draw correctly.
|
|
ProxyStyle* newProxy = new ProxyStyle(qApp->style());
|
|
pb4->setStyle(newProxy);
|
|
|
|
layout->addWidget(pb4);
|
|
|
|
QPushButton *pb5 = new QPushButton("ProxyStyle then StyleSheet ", w);
|
|
pb5->setStyle(proxy);
|
|
pb5->setStyleSheet(styleSheet);
|
|
layout->addWidget(pb5);
|
|
|
|
w->show();
|
|
|
|
QTest::qWait(100);
|
|
|
|
// Test for QTBUG-7198 - style sheet overrides custom element size
|
|
QStyleOptionViewItemV4 opt;
|
|
opt.initFrom(w);
|
|
opt.features |= QStyleOptionViewItemV2::HasCheckIndicator;
|
|
QVERIFY(pb5->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator,
|
|
&opt, pb5).width() == 3);
|
|
delete w;
|
|
delete proxy;
|
|
delete newProxy;
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::dialogButtonBox()
|
|
{
|
|
QDialogButtonBox box;
|
|
box.addButton(QDialogButtonBox::Ok);
|
|
box.addButton(QDialogButtonBox::Cancel);
|
|
box.setStyleSheet("/** */ ");
|
|
box.setStyleSheet(QString()); //should not crash
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::emptyStyleSheet()
|
|
{
|
|
//empty stylesheet should not change anything
|
|
qApp->setStyleSheet(QString());
|
|
QWidget w;
|
|
QHBoxLayout layout(&w);
|
|
w.setLayout(&layout);
|
|
#ifdef QT3_SUPPORT
|
|
layout.addWidget(new Q3ProgressBar(&w)); //task 231137
|
|
#endif
|
|
layout.addWidget(new QPushButton("push", &w));
|
|
layout.addWidget(new QToolButton(&w));
|
|
QLabel label("toto", &w);
|
|
label.setFrameShape(QLabel::Panel);
|
|
label.setFrameShadow(QLabel::Sunken);
|
|
layout.addWidget(&label); //task 231137
|
|
layout.addWidget(new QTableWidget(200,200, &w));
|
|
layout.addWidget(new QProgressBar(&w));
|
|
layout.addWidget(new QLineEdit(&w));
|
|
layout.addWidget(new QSpinBox(&w));
|
|
layout.addWidget(new QComboBox(&w));
|
|
layout.addWidget(new QDateEdit(&w));
|
|
layout.addWidget(new QGroupBox("some text", &w));
|
|
|
|
w.show();
|
|
#ifdef Q_WS_X11
|
|
qt_x11_wait_for_window_manager(&w);
|
|
#endif
|
|
//workaround the fact that the label sizehint is one pixel different the first time.
|
|
label.setIndent(0); //force to recompute the sizeHint:
|
|
w.setFocus();
|
|
QTest::qWait(100);
|
|
|
|
QImage img1(w.size(), QImage::Format_ARGB32);
|
|
w.render(&img1);
|
|
|
|
w.setStyleSheet("/* */");
|
|
QTest::qWait(100);
|
|
|
|
QImage img2(w.size(), QImage::Format_ARGB32);
|
|
w.render(&img2);
|
|
|
|
if(img1 != img2) {
|
|
img1.save("emptyStyleSheet_img1.png");
|
|
img2.save("emptyStyleSheet_img2.png");
|
|
}
|
|
|
|
QCOMPARE(img1,img2);
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::toolTip()
|
|
{
|
|
qApp->setStyleSheet(QString());
|
|
QWidget w;
|
|
QHBoxLayout layout(&w);
|
|
w.setLayout(&layout);
|
|
|
|
QWidget *wid1 = new QGroupBox(&w);
|
|
layout.addWidget(wid1);
|
|
wid1->setStyleSheet("QToolTip { background: #ae2; } #wid3 > QToolTip { background: #0b8; } ");
|
|
QVBoxLayout *layout1 = new QVBoxLayout(wid1);
|
|
wid1->setLayout(layout1);
|
|
wid1->setToolTip("this is wid1");
|
|
wid1->setObjectName("wid1");
|
|
|
|
QWidget *wid2 = new QPushButton("wid2", wid1);
|
|
layout1->addWidget(wid2);
|
|
wid2->setStyleSheet("QToolTip { background: #f81; } ");
|
|
wid2->setToolTip("this is wid2");
|
|
wid2->setObjectName("wid2");
|
|
|
|
QWidget *wid3 = new QPushButton("wid3", wid1);
|
|
layout1->addWidget(wid3);
|
|
wid3->setToolTip("this is wid3");
|
|
wid3->setObjectName("wid3");
|
|
|
|
QWidget *wid4 = new QPushButton("wid4", &w);
|
|
layout.addWidget(wid4);
|
|
wid4->setToolTip("this is wid4");
|
|
wid4->setObjectName("wid4");
|
|
|
|
w.show();
|
|
QTest::qWait(100);
|
|
|
|
QColor normalToolTip = qApp->palette().toolTipBase().color();
|
|
QList<QWidget *> widgets;
|
|
QList<QColor> colors;
|
|
|
|
|
|
//tooltip on the widget without stylesheet, then to othes widget, including one without stylesheet
|
|
//(the tooltip will be reused but his colour must change)
|
|
widgets << wid4 << wid1 << wid2 << wid3 << wid4;
|
|
colors << normalToolTip << "#ae2" << "#f81" << "#0b8" << normalToolTip;
|
|
|
|
for (int i = 0; i < widgets.count() ; i++)
|
|
{
|
|
QWidget *wid = widgets.at(i);
|
|
QColor col = colors.at(i);
|
|
|
|
QToolTip::showText( QPoint(0,0) , "This is " + wid->objectName(), wid);
|
|
|
|
QWidget *tooltip = 0;
|
|
foreach (QWidget *widget, QApplication::topLevelWidgets()) {
|
|
if (widget->inherits("QTipLabel") && widget->isVisible()) {
|
|
tooltip = widget;
|
|
break;
|
|
}
|
|
}
|
|
QVERIFY(tooltip);
|
|
QCOMPARE(tooltip->palette().color(tooltip->backgroundRole()), col);
|
|
}
|
|
|
|
QToolTip::showText( QPoint(0,0) , "This is " + wid3->objectName(), wid3);
|
|
QTest::qWait(100);
|
|
delete wid3; //should not crash;
|
|
QTest::qWait(10);
|
|
foreach (QWidget *widget, QApplication::topLevelWidgets()) {
|
|
widget->update(); //should not crash either
|
|
}
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::embeddedFonts()
|
|
{
|
|
//task 235622 and 210551
|
|
QSpinBox spin;
|
|
spin.show();
|
|
spin.setStyleSheet("QSpinBox { font-size: 32px; }");
|
|
QTest::qWait(20);
|
|
QLineEdit *embedded = spin.findChild<QLineEdit *>();
|
|
QVERIFY(embedded);
|
|
QCOMPARE(spin.font().pixelSize(), 32);
|
|
QCOMPARE(embedded->font().pixelSize(), 32);
|
|
|
|
QMenu *menu = embedded->createStandardContextMenu();
|
|
menu->show();
|
|
QTest::qWait(20);
|
|
QVERIFY(menu);
|
|
QVERIFY(menu->font().pixelSize() != 32);
|
|
QCOMPARE(menu->font().pixelSize(), qApp->font(menu).pixelSize());
|
|
|
|
//task 242556
|
|
QComboBox box;
|
|
box.setEditable(true);
|
|
box.addItems(QStringList() << "First" << "Second" << "Third");
|
|
box.setStyleSheet("QComboBox { font-size: 32px; }");
|
|
box.show();
|
|
embedded = box.findChild<QLineEdit *>();
|
|
QVERIFY(embedded);
|
|
QTest::qWait(20);
|
|
QCOMPARE(box.font().pixelSize(), 32);
|
|
QCOMPARE(embedded->font().pixelSize(), 32);
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::opaquePaintEvent_data()
|
|
{
|
|
QTest::addColumn<QString>("stylesheet");
|
|
QTest::addColumn<bool>("transparent");
|
|
QTest::addColumn<bool>("styled");
|
|
|
|
QTest::newRow("none") << QString::fromLatin1("/* */") << false << false;
|
|
QTest::newRow("background black ") << QString::fromLatin1("background: black;") << false << true;
|
|
QTest::newRow("background qrgba") << QString::fromLatin1("background: rgba(125,0,0,125);") << true << true;
|
|
QTest::newRow("background transparent") << QString::fromLatin1("background: transparent;") << true << true;
|
|
QTest::newRow("border native") << QString::fromLatin1("border: native;") << false << false;
|
|
QTest::newRow("border solid") << QString::fromLatin1("border: 2px solid black;") << true << true;
|
|
QTest::newRow("border transparent") << QString::fromLatin1("background: black; border: 2px solid rgba(125,0,0,125);") << true << true;
|
|
QTest::newRow("margin") << QString::fromLatin1("margin: 25px;") << true << true;
|
|
QTest::newRow("focus") << QString::fromLatin1("*:focus { background: rgba(125,0,0,125) }") << true << true;
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::opaquePaintEvent()
|
|
{
|
|
QFETCH(QString, stylesheet);
|
|
QFETCH(bool, transparent);
|
|
QFETCH(bool, styled);
|
|
|
|
QWidget tl;
|
|
QWidget cl(&tl);
|
|
cl.setAttribute(Qt::WA_OpaquePaintEvent, true);
|
|
cl.setAutoFillBackground(true);
|
|
cl.setStyleSheet(stylesheet);
|
|
cl.ensurePolished();
|
|
QCOMPARE(cl.testAttribute(Qt::WA_OpaquePaintEvent), !transparent);
|
|
QCOMPARE(cl.testAttribute(Qt::WA_StyledBackground), styled);
|
|
QCOMPARE(cl.autoFillBackground(), !styled );
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::complexWidgetFocus()
|
|
{
|
|
// This test is a simplified version of the focusColors() test above.
|
|
|
|
// Tests if colors can be changed by altering the focus of the widget.
|
|
// To avoid messy pixel-by-pixel comparison, we assume that the goal
|
|
// is reached if at least ten pixels of the right color can be found in
|
|
// the image.
|
|
// For this reason, we use unusual and extremely ugly colors! :-)
|
|
|
|
QDialog frame;
|
|
frame.setStyleSheet("*:focus { background: black; color: black } "
|
|
"QSpinBox::up-arrow:focus, QSpinBox::down-arrow:focus { width: 7px; height: 7px; background: #ff0084 } "
|
|
"QComboBox::down-arrow:focus { width: 7px; height: 7px; background: #ff0084 }"
|
|
"QSlider::handle:horizontal:focus { width: 7px; height: 7px; background: #ff0084 } ");
|
|
|
|
QList<QWidget *> widgets;
|
|
widgets << new QSpinBox;
|
|
widgets << new QComboBox;
|
|
widgets << new QSlider(Qt::Horizontal);
|
|
|
|
QLayout* layout = new QGridLayout;
|
|
layout->addWidget(new QLineEdit); // Avoids initial focus.
|
|
foreach (QWidget *widget, widgets)
|
|
layout->addWidget(widget);
|
|
frame.setLayout(layout);
|
|
|
|
frame.show();
|
|
QTest::qWaitForWindowShown(&frame);
|
|
QApplication::setActiveWindow(&frame);
|
|
foreach (QWidget *widget, widgets) {
|
|
widget->setFocus();
|
|
QApplication::processEvents();
|
|
|
|
QImage image(frame.width(), frame.height(), QImage::Format_ARGB32);
|
|
frame.render(&image);
|
|
if (image.depth() < 24) {
|
|
QSKIP("Test doesn't support color depth < 24", SkipAll);
|
|
}
|
|
|
|
QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)),
|
|
(QString::fromLatin1(widget->metaObject()->className())
|
|
+ " did not contain text color #ff0084, using style "
|
|
+ QString::fromLatin1(qApp->style()->metaObject()->className()))
|
|
.toLocal8Bit().constData());
|
|
}
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::task188195_baseBackground()
|
|
{
|
|
QTreeView tree;
|
|
tree.setStyleSheet( "QTreeView:disabled { background-color:#ab1251; }" );
|
|
tree.show();
|
|
QTest::qWait(20);
|
|
QImage image(tree.width(), tree.height(), QImage::Format_ARGB32);
|
|
|
|
tree.render(&image);
|
|
QVERIFY(testForColors(image, tree.palette().base().color()));
|
|
QVERIFY(!testForColors(image, QColor(0xab, 0x12, 0x51)));
|
|
|
|
tree.setEnabled(false);
|
|
tree.render(&image);
|
|
QVERIFY(testForColors(image, QColor(0xab, 0x12, 0x51)));
|
|
|
|
tree.setEnabled(true);
|
|
tree.render(&image);
|
|
QVERIFY(testForColors(image, tree.palette().base().color()));
|
|
QVERIFY(!testForColors(image, QColor(0xab, 0x12, 0x51)));
|
|
|
|
QTableWidget table(12, 12);
|
|
table.setItem(0, 0, new QTableWidgetItem());
|
|
table.setStyleSheet( "QTableView {background-color: #ff0000}" );
|
|
table.show();
|
|
QTest::qWait(20);
|
|
image = QImage(table.width(), table.height(), QImage::Format_ARGB32);
|
|
table.render(&image);
|
|
QVERIFY(testForColors(image, Qt::red, true));
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::task232085_spinBoxLineEditBg()
|
|
{
|
|
// This test is a simplified version of the focusColors() test above.
|
|
|
|
// Tests if colors can be changed by altering the focus of the widget.
|
|
// To avoid messy pixel-by-pixel comparison, we assume that the goal
|
|
// is reached if at least ten pixels of the right color can be found in
|
|
// the image.
|
|
// For this reason, we use unusual and extremely ugly colors! :-)
|
|
|
|
QSpinBox *spinbox = new QSpinBox;
|
|
spinbox->setValue(8888);
|
|
|
|
QDialog frame;
|
|
QLayout* layout = new QGridLayout;
|
|
|
|
QLineEdit* dummy = new QLineEdit; // Avoids initial focus.
|
|
|
|
// We only want to test the line edit colors.
|
|
spinbox->setStyleSheet("QSpinBox:focus { background: #e8ff66; color: #ff0084 } "
|
|
"QSpinBox::up-button, QSpinBox::down-button { background: black; }");
|
|
|
|
layout->addWidget(dummy);
|
|
layout->addWidget(spinbox);
|
|
frame.setLayout(layout);
|
|
|
|
frame.show();
|
|
QTest::qWaitForWindowShown(&frame);
|
|
QApplication::setActiveWindow(&frame);
|
|
spinbox->setFocus();
|
|
QApplication::processEvents();
|
|
|
|
QImage image(frame.width(), frame.height(), QImage::Format_ARGB32);
|
|
frame.render(&image);
|
|
if (image.depth() < 24) {
|
|
QSKIP("Test doesn't support color depth < 24", SkipAll);
|
|
}
|
|
|
|
QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)),
|
|
(QString::fromLatin1(spinbox->metaObject()->className())
|
|
+ " did not contain background color #e8ff66, using style "
|
|
+ QString::fromLatin1(qApp->style()->metaObject()->className()))
|
|
.toLocal8Bit().constData());
|
|
QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)),
|
|
(QString::fromLatin1(spinbox->metaObject()->className())
|
|
+ " did not contain text color #ff0084, using style "
|
|
+ QString::fromLatin1(qApp->style()->metaObject()->className()))
|
|
.toLocal8Bit().constData());
|
|
}
|
|
|
|
class ChangeEventWidget : public QWidget
|
|
{ public:
|
|
void changeEvent(QEvent * event)
|
|
{
|
|
if(event->type() == QEvent::StyleChange) {
|
|
static bool recurse = false;
|
|
if (!recurse) {
|
|
recurse = true;
|
|
QStyle *style = new QMotifStyle;
|
|
style->setParent(this);
|
|
setStyle(style);
|
|
recurse = false;
|
|
}
|
|
}
|
|
QWidget::changeEvent(event);
|
|
}
|
|
};
|
|
|
|
void tst_QStyleSheetStyle::changeStyleInChangeEvent()
|
|
{ //must not crash;
|
|
ChangeEventWidget wid;
|
|
wid.ensurePolished();
|
|
wid.setStyleSheet(" /* */ ");
|
|
wid.ensurePolished();
|
|
wid.setStyleSheet(" /* ** */ ");
|
|
wid.ensurePolished();
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::QTBUG11658_cachecrash()
|
|
{
|
|
//should not crash
|
|
class Widget : public QWidget
|
|
{
|
|
public:
|
|
Widget(QWidget *parent = 0)
|
|
: QWidget(parent)
|
|
{
|
|
QVBoxLayout* pLayout = new QVBoxLayout(this);
|
|
QCheckBox* pCheckBox = new QCheckBox(this);
|
|
pLayout->addWidget(pCheckBox);
|
|
setLayout(pLayout);
|
|
|
|
QString szStyleSheet = QLatin1String("* { color: red; }");
|
|
qApp->setStyleSheet(szStyleSheet);
|
|
qApp->setStyle(QStyleFactory::create(QLatin1String("Windows")));
|
|
}
|
|
};
|
|
|
|
Widget *w = new Widget();
|
|
delete w;
|
|
w = new Widget();
|
|
w->show();
|
|
|
|
QTest::qWaitForWindowShown(w);
|
|
delete w;
|
|
qApp->setStyleSheet(QString());
|
|
}
|
|
|
|
void tst_QStyleSheetStyle::QTBUG15910_crashNullWidget()
|
|
{
|
|
struct : QWidget {
|
|
virtual void paintEvent(QPaintEvent* ) {
|
|
QStyleOption opt;
|
|
opt.init(this);
|
|
QPainter p(this);
|
|
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, 0);
|
|
style()->drawPrimitive(QStyle::PE_Frame, &opt, &p, 0);
|
|
style()->drawControl(QStyle::CE_PushButton, &opt, &p, 0);
|
|
}
|
|
} w;
|
|
w.setStyleSheet("* { background-color: white; color:black; border 3px solid yellow }");
|
|
w.show();
|
|
QTest::qWaitForWindowShown(&w);
|
|
}
|
|
|
|
|
|
QTEST_MAIN(tst_QStyleSheetStyle)
|
|
#include "tst_qstylesheetstyle.moc"
|
|
|