Skip to content

Commit

Permalink
fix: can not be fixed widget style
Browse files Browse the repository at this point in the history
Change-Id: I34b0b6bd83940b042c5c07387b398e282c66359e
  • Loading branch information
zccrs committed Jan 22, 2018
1 parent d11317f commit 5bf22c1
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 17 deletions.
10 changes: 8 additions & 2 deletions src/dtkwidget_global.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,16 @@ namespace Widget

#define D_THEME_INIT_WIDGET(className, ...) do{\
DThemeManager * manager = DThemeManager::instance(); \
this->setStyleSheet(this->styleSheet() + manager->getQssForWidget(#className, this)); \
{const QString &sheet = this->styleSheet() + manager->getQssForWidget(#className, this); \
if (!sheet.isEmpty()) this->setStyleSheet(sheet); \
} \
connect(manager, &DThemeManager::themeChanged, this, [this, manager] (QString) { \
this->setStyleSheet(manager->getQssForWidget(#className, this)); \
const QString &sheet = manager->getQssForWidget(#className, this); \
if (!sheet.isEmpty()) this->setStyleSheet(sheet); \
});\
connect(manager, &DThemeManager::widgetThemeChanged, this, [this, manager] (QWidget *w, QString) { \
if (w == this) this->setStyleSheet(manager->getQssForWidget(#className, this)); \
}); \
QStringList list = QString(#__VA_ARGS__).replace(" ", "").split(",");\
const QMetaObject *self = metaObject();\
Q_FOREACH (const QString &str, list) {\
Expand Down
102 changes: 88 additions & 14 deletions src/widgets/dthememanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

#include <QDebug>

#include <private/qstylesheetstyle_p.h>

#include "dthememanager.h"
#include "dapplication.h"

Expand Down Expand Up @@ -61,14 +63,34 @@ QString DThemeManager::theme() const
return m_theme;
}

QString DThemeManager::theme(const QWidget *widget, QWidget **baseWidget) const
{
QString theme;

if (baseWidget)
*baseWidget = nullptr;

do {
theme = widget->property("_d_dtk_theme").toString();
if (!theme.isEmpty()) {
if (baseWidget)
*baseWidget = const_cast<QWidget*>(widget);

break;
}
widget = widget->isWindow() ? 0 : widget->parentWidget();
} while (widget);

return theme.isEmpty() ? m_theme : theme;
}

/*!
* \brief DThemeManager::setTheme sets the application theme.
* \param theme is the theme name to be set.
*/
void DThemeManager::setTheme(const QString theme)
{
if (m_theme != theme) {

QStyle *style = Q_NULLPTR;

// TODO: remove this shit in the future.
Expand Down Expand Up @@ -105,6 +127,48 @@ static QString getObjectClassName(const QObject *obj)
return widget_type_list.isEmpty() ? type_name : widget_type_list.last();
}

static void emitThemeChanged(DThemeManager *manager, QWidget *widget, const QString &theme)
{
Q_EMIT manager->widgetThemeChanged(widget, theme);

for (QObject *child : widget->children()) {
if (QWidget *cw = qobject_cast<QWidget*>(child)) {
if (cw->property("_d_dtk_theme").isValid())
continue;

emitThemeChanged(manager, cw, theme);
}
}
}

static void setStyle(QWidget *widget, QStyle *style)
{
widget->setStyle(style);

for (QObject *child : widget->children()) {
if (QWidget *cw = qobject_cast<QWidget*>(child)) {
if (cw->property("_d_dtk_theme").isValid())
continue;

setStyle(cw, style);
}
}
}

static void inseritStyle(QWidget *widget, const QWidget *baseWidget)
{
if (widget == baseWidget)
return;

QStyle *base_style = baseWidget ? baseWidget->style() : qApp->style();

if (base_style->inherits("QStyleSheetStyle")) {
base_style = static_cast<QStyleSheetStyle*>(base_style)->base;
}

widget->setStyle(base_style);
}

/*!
* \brief DThemeManager::setTheme sets theme on a widget.
* \param widget is the target widget.
Expand All @@ -114,6 +178,23 @@ void DThemeManager::setTheme(QWidget *widget, const QString theme)
{
Q_ASSERT(widget);

if (theme.isEmpty()) {
QString old_theme = this->theme(widget);

widget->setProperty("_d_dtk_theme", QVariant());

QWidget *baseWidget = nullptr;

if (this->theme(widget, &baseWidget) != old_theme) {
emitThemeChanged(this, widget, this->theme(widget));
}

inseritStyle(widget, baseWidget);

return;
}

const QString &old_theme = this->theme(widget);
QStyle *style = Q_NULLPTR;

// TODO: remove this shit in the future.
Expand All @@ -135,10 +216,11 @@ void DThemeManager::setTheme(QWidget *widget, const QString theme)
}

if (style) {
widget->setStyle(style);
setStyle(widget, style);
}

widget->setStyleSheet(getQssForWidget(getObjectClassName(widget), theme));
if (old_theme != theme)
emitThemeChanged(this, widget, theme);
}

/*!
Expand All @@ -160,9 +242,9 @@ QString DThemeManager::getQssForWidget(const QString className, const QString &t
if (themeFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qss = themeFile.readAll();
themeFile.close();
} else {
} /*else {
qWarning() << "open qss file failed" << themeURL << themeFile.errorString();
}
}*/

return qss;
}
Expand All @@ -179,15 +261,7 @@ QString DThemeManager::getQssForWidget(const QString className, const QWidget *w
{
Q_ASSERT(widget);

QString theme;

do {
theme = widget->property("_d_dtk_theme").toString();
if (!theme.isEmpty()) { break; }
widget = widget->parentWidget();
} while (widget);

return getQssForWidget(className, theme);
return getQssForWidget(className, theme(widget));
}

/*!
Expand Down
4 changes: 3 additions & 1 deletion src/widgets/dthememanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ class DThemeManager : public QObject
static DThemeManager *instance();

QString theme() const;
QString theme(const QWidget *widget, QWidget **baseWidget = nullptr) const;
void setTheme(const QString theme);
void setTheme(QWidget *widget, const QString theme);

QString getQssForWidget(const QString className, const QString &theme = "") const;
QString getQssForWidget(const QString className, const QString &theme = QString()) const;
QString getQssForWidget(const QString className, const QWidget *widget) const;
QString getQssForWidget(const QWidget *widget) const;

Expand All @@ -48,6 +49,7 @@ public Q_SLOTS:

Q_SIGNALS:
void themeChanged(QString theme);
void widgetThemeChanged(QWidget *widget, QString theme);

protected:
DThemeManager();
Expand Down

0 comments on commit 5bf22c1

Please sign in to comment.