Theme support for app



  • Hello, I have a whole stylesheet (css) inside styleSheet property of MainWindow.

    I would like to ask you how to make possible that user could change a theme of app.

    My idea is to create 2 files. 1st file will be for "light" theme and 2nd file will be for "dark" theme, these files contains a stylesheet.

    And if user selects a light theme then app will load a stylesheet from 1st file and if user selects a dark theme then app will load that second one.

    Please how to do that? And is this good aproach? Or is something better?

    Thank you


  • Lifetime Qt Champion

    Hi,

    Have your two stylesheets in your application resources and load the appropriate one when the user makes its selection.



  • Yes, I find

    qApp->setStyleSheet();
    

    but how to access a object App inside MainWindow?


  • Lifetime Qt Champion

    Using the qApp macro that is available when you #include <QApplication> ?



  • Ah yes, thanks, but this is my code:

    #include "settings.h"
    #include "ui_settings.h"
    
    #include <QApplication>
    
    settings::settings(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::settings)
    {
        ui->setupUi(this);
    }
    
    settings::~settings()
    {
        delete ui;
    }
    
    void settings::on_pushButton_clicked()
    {
        qApp->setStyleSheet("QMainWindow { background: rgb(130, 255, 47); }");
        this->close();
    }
    

    It is a settings dialog, why it doesn't change a background of MainWindow?


  • Qt Champions 2016

    @t0msk said in Theme support for app:

    "QMainWindow { background: rgb(130, 255, 47); }");

    Hi
    You tell that only objects of type QMainWindow would be affected
    and that do not include a QDialog.

    Please see selector types
    http://doc.qt.io/qt-5/stylesheet-syntax.html

    Its pretty important to understand or it becomes a mess to handle :)



  • @mrjj said in Theme support for app:

    @t0msk said in Theme support for app:

    "QMainWindow { background: rgb(130, 255, 47); }");

    Hi
    You tell that only objects of type QMainWindow would be affected
    and that do not include a QDialog.

    Please see selector types
    http://doc.qt.io/qt-5/stylesheet-syntax.html

    Its pretty important to understand or it becomes a mess to handle :)

    Yes I understand, but it doesn't change a different window (QMainWindow). I want to apply that css for whole app.


  • Qt Champions 2016

    @t0msk
    ok in that case, you should use
    setStyleSheet of the QApp
    http://doc.qt.io/qt-5/qapplication.html#styleSheet-prop

    But again, if u say "only mainwindow" in the ccs file, it wont matter if you set it on application. it still only applies to Mainwindow types of object.
    ok ?
    Im asking again as the sample you show is wrong on a logical level

    QDialog(parent), <<< its a DIALOG
    void settings::on_pushButton_clicked()
    {
    qApp->setStyleSheet("QMainWindow { background: rgb(130, xxx
    You ONLY affecting mainwindows.
    So this can never work if you think that QDialog will use settings assigned to QMainWindow type.



  • @mrjj said in Theme support for app:

    @t0msk
    ok in that case, you should use
    setStyleSheet of the QApp
    http://doc.qt.io/qt-5/qapplication.html#styleSheet-prop

    But again, if u say "only mainwindow" in the ccs file, it wont matter if you set it on application. it still only applies to Mainwindow types of object.
    ok ?
    Im asking again as the sample you show is wrong on a logical level

    QDialog(parent), <<< its a DIALOG
    void settings::on_pushButton_clicked()
    {
    qApp->setStyleSheet("QMainWindow { background: rgb(130, xxx
    You ONLY affecting mainwindows.
    So this can never work if you think that QDialog will use settings assigned to QMainWindow type.

    You don't understand me. I know that QMainWindow is not QDialog..

    But I have 2 windows, one is QDialog (settings window) and second is QMainWindow (main program), I know that design of QDialog doesn't change, but if I push button it doesn't change design of the second window QMainWindow (main program).

    Ah it works now, it didn't work because I had fixed css in ui file. So it means that if I set some css through Qt Designer then

    qApp->setStyleSheet
    

    doesn't override it?


  • Qt Champions 2016

    @t0msk
    Ah so the fact that escaped you is
    that stylesheet are cascading from parent to childs.

    Since the mainwindow is NOT a child of the dialog, setting it there will not change
    any QMainwindows.

    Anyways, use QApp setStyleSheet will.


  • Qt Champions 2016

    @t0msk said in Theme support for app:

    doesn't override it?

    Depends on order.

    You set QApp in main

    In setupUI, any style sheet will override.

    Do you need multiple stylesheets? I always makes a mess when i try.
    One big one set to App in main always works the cleanest.



  • @mrjj
    I have main, mainwindow and settings. My idea is that, in main it will load stylesheet from config QSettings.. and then if user want to change it, he will change it in settings dialog, settings dialog then write that change to QSettings and apply a new stylesheet, it works, but I don't know, why it (settings) doesn't overwrite stylesheet defined in QtDesigner.


  • Qt Champions 2016

    @t0msk said in Theme support for app:

    doesn't overwrite stylesheet defined in QtDesigner.

    It should. If you set it on QApp()->setStyleSheet in the dialog
    But not tested it. Might not override when already set.
    Note that Designer do NOT do anything special.
    It simply calls setStyleSheet in setupUI

    Try
    setStyleSheet(QString());
    in ctor of main and see if it then overrides.
    Note. do not use "" as its not the same as no stylesheet



  • @mrjj said in Theme support for app:

    QString(

    I tried:

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        qApp->setStyleSheet(QString("QMainWindow { background: rgb(130, 255, 47); }"));
    }
    

    and it didn't override stylesheet defined in Designer. I tried it in main.cpp too and no success.


  • Qt Champions 2016

    @t0msk said in Theme support for app:
    Lets assume that the cascading effect excludes widget with non empty stylesheets.
    Can you try.

    {
        ui->setupUi(this);
        setStyleSheet( QString() );
        qApp->setStyleSheet(QString("QMainWindow { background: rgb(130, 255, 47); }"));
    }``


  • @mrjj
    Thank you, this works, but why, I don't understand.. and what is this line?

    setStyleSheet( QString() );
    

    why there is no "qApp->"? It is setStyleSheet for what? Why am I passing empty QString?


  • Qt Champions 2016

    @t0msk
    hi
    I clear the stylesheet of mainwindow
    this->setStyleSheet( QString() );
    the QString() constructs an empty string object.
    Which is different from setStyleSheet( "" );
    So it seems that it will not override other already set stylesheets.
    But if you clear it (by setting to empty.string(). Using "" would be empty stylesheet.)
    then it works.



  • @mrjj
    aha, thanks :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.