Search code examples
c++qtqt5qapplication

Qt: Getting the current application palette


I have a class that composes a palette and assigns it to the application using QApplication::instance()->setPalette(QPalette palette).

And it effectively works.

But then I try to use QPalette QApplication::instance()->palette() to extract some colours.

But here it does not work, it just returns the default palette, not the current one.

After I have discovered that it is working as supposed and described in the documentation.

And now I have just 2 questions:

  1. Why it is working in such a strange, useless and counter-intuitive mode?
  2. How I can retrieve the palette which was set using QApplication::instance()->setPalette(QPalette palette)?

P.S. No, I can't keep that palette elsewhere.


Solution

  • I think it is an issue of your Qt version (you marked the question as Qt 5 but didn't indicate a specific version), or you have something else in your project that is resetting the palette (you mentioned it has a large code base).

    This minimum example shows correct behavior, at least with Qt 5.12.3 32bits, Windows, VS 2017:

    #include <QApplication>
    #include <QPalette>
    #include <QDebug>
    #include <QTimer>
    #include <QWidget>
    
    int main(int argc, char *argv[])
    {
      QApplication a(argc, argv);
    
      const auto group = QPalette::Active;
      const auto role = QPalette::Text;
    
      auto palette = QApplication::palette();
      qDebug() << "palette before:" << palette.color(group, role).name();
    
      palette.setColor(group, role, "#123456");
      qDebug() << "palette set:" << palette.color(group, role).name();
    
      QApplication::setPalette(palette);
    
      const auto palette2 = QApplication::palette();
      qDebug() << "palette after:" << palette2.color(group, role).name();
    
      QTimer::singleShot(100, [=]() { // check palette after the events loop has started
        const auto palette3 = QApplication::palette();
        qDebug() << "palette after 100ms:" << palette3.color(group, role).name();    
      });
    
      QWidget w;
      w.show();
    
      return a.exec();
    }
    

    enter image description here

    I've used QApplication::palette my self to retrieve custom palettes in different projects and had no issues at all.

    QGuiApplication::setPalette is documented to change the default palette, so basically I think default palette means the palette used if a widget doesn't specify the other one; not the default system palette.

    PS: I couldn't make it compile when using QApplication::instance()->setPalette since QApplication doesn't defines instance() but it falls to QCoreApplication::instance(), which obviously returns a QCoreApplication. Probably just a typo when you wrote the question, but I thought it deserved some lines. Given that the palette related methods are static, I decided to use those in the example, but I had the same results using the singleton from qApp.