Как изменить только одно свойство:значение в Qt стилей

Я пишу код новичка Qt5 на OSX Mavericks и хотел бы переопределить только одно свойство:пару значений таблицы стилей для данного виджета.

Если я запускаю следующий автономный демонстрационный код:

#include <QApplication>
#include <QMainWindow>
#include <QtGui>
#include <QPushButton>

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

    QMainWindow* mw = new QMainWindow();

    QPushButton* AButton = new QPushButton( "A Button", mw );

    mw->show();

    return app.exec();
}

Я получаю хорошую кнопку с настройками стиля Macintosh по умолчанию-закругленные углы, стандартный OSX-синий цвет при нажатии и т. д.:

QPushButton with OSX defaults

Если, однако, я установил таблицу стилей, чтобы сделать цвет кнопки фона красным, кажется Я теряю все остальные значения стиля OSX по умолчанию в процессе-больше нет закругленных углов,стандартных полей и т. д.:

#include <QApplication>
#include <QMainWindow>
#include <QtGui>
#include <QPushButton>

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

    QMainWindow* mw = new QMainWindow();

    QPushButton* AButton = new QPushButton( "A Button", mw );

    AButton->setStyleSheet("QPushButton { background-color: red; }");

    mw->show();

    return app.exec();
}

вот результат:

QPushButton style override, with loss of other OSX defaults

Как я могу переопределить только одно свойство:пара значений при сохранении остальных элементов стиля для виджета,например, в приведенном выше примере сделайте цвет фона красным, но сохраните все границы округления, поля и т. д. то же самое?

спасибо

2 ответов


ваш анализ в вашем комментарии, что вызов QApplication:: setStyleSheet () полностью заменит текущий активный стиль неверным. Вы правы, что текущий стиль заменяется на QStyleSheetStyle. Однако,QStyleSheetStyle делегирует свой рисунок исходному стилю,в вашем случае стилю Mac. Если вы посмотрите на источник QStyleSheetStyle, вы увидите это во многих местах, призывы к baseStyle()->drawControl().

это означает, что таблицы стилей работают на любом стиль. В твоем случае это явно не сработало, так что случилось? QStyleSheetStyle возвращается к рисованию в стиле Windows, если правила таблицы стилей не могут быть применены к базовому стилю. Это означает, что некоторые правила таблицы стилей работают хорошо, в то время как другие запускают резерв. Правила спровоцировало откат.

Я не думаю, что задокументировано, какие правила запускают резерв. Для этого нам нужно посмотреть на источник, в данном случае QStyleSheetStyle:: drawControl (). Мы найдите там следующее:

case CE_PushButton:
    if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
        if (rule.hasDrawable() || rule.hasBox() || rule.hasPosition() || rule.hasPalette() ||
                ((btn->features & QStyleOptionButton::HasMenu) && hasStyleRule(w, PseudoElement_PushButtonMenuIndicator))) {
            ParentStyle::drawControl(ce, opt, p, w);
            return;
        }
    }

ParentSyle - это резервный стиль Windows. Правило background-color делает rule.hasPalette() return true, поэтому запуск резервного копирования.


как освещено в параллельном столбе как получить всю таблицу стилей Qt для QMacStyle, мой первоначальный вопрос был основан на запутанной предпосылке.

в Qt, все виджеты оформлены через QStyle (). По умолчанию для кода Qt на OSX (как и в моем первом блоке демонстрационного кода в исходном вопросе) виджеты Qt стилизованы подклассом QStyle () называется QMacStyle () (на самом деле теперь, по-видимому, производная от QProxyStyle () на странице QMacStyle -- Файл Не Найден).

вызов функции setStyleSheet (), как и в моем втором блоке демонстрационного кода в исходном вопросе, создает экземпляр QStyleSheetStyle (), который затем полностью заменяет любой QStyle, используемый для виджета заранее-в этом случае симпатичный QMacStyle, который я надеялся сохранить. Подробности реализации можно увидеть, например, в qtbase/src/widgets/kernel/qapplication.cpp на QApplication::setStyleSheet() метод. Сам QStyleSheetStyle () находится в qtbase/src/widgets/styles/qstylesheetstyle.cpp. Как точка мелочи, QStyleSheetStyle () происходит от QWindowsStyle (), следовательно, внешний вид windows-ish для модифицированной кнопки в моем исходном вопросе.

короткая история заключается в том, что Таблицы Стилей Qt реализованы поверх QStyle(). Вызов setStyleSheet() неявно решает, что вы собираетесь использовать QStyleSheetStyle () вместо QMacStyle ().

сообщение take-home заключается в том, что при стилизации виджетов вам нужно выберите свой подход, с компромиссами в любом случае. Вам нужно выбрать, какой QStyle () вы собираетесь использовать. Если вы запускаете код по умолчанию на Mac, вы решили начать с QMacStyle(). Затем вы можете изменить этот QStyle () на существующую документацию. Если вы вызываете setStyleSheet(), вы неявно решили начать с QStyleSheetStyle (), который по умолчанию имеет внешний вид QWindowsStyle (). Любое свойство таблицы стилей-значения, которые вы применяете, изменят этот внешний вид.

для меня как было указано выше,есть два варианта. Одна из них заключается в том, что человек может вносить любые изменения во внешность полностью с помощью механизмов, доступных через QStyle (). Как это сделать, задокументировано в другом месте. Другой вариант-создать с нуля таблицу стилей, которая воспроизводила бы внешний вид Mac для рассматриваемого виджета, а затем изменить ее с помощью требуемых настроек и применить ее через setStyleSheet().

в идеальном мире кто-то бы пошел через это упражнение уже-то есть переваривается qtbase/src/widgets/styles/qmacstyle_mac.mm в его эквивалент таблицы стилей - однако эта работа кажется обременительной, и не похоже, что кто-то это сделал, по крайней мере, не с публичной публикацией. Я предполагаю, что другим отдаленно возможным вариантом было бы переопределение QStyleSheetStyle на основе QMacStyle вместо QWindowsStyle, а затем каким-то образом интегрировать результат обратно в код (возможно, иметь setStyleSheet( qstyle* baseStyle, QString styleSheet)). Однако это далеко не новичок в Qt навыки, не говоря уже о текущей миссии.