8

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.

cbuchart
  • 10,847
  • 9
  • 53
  • 93

1 Answers1

5

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.

cbuchart
  • 10,847
  • 9
  • 53
  • 93
  • 1
    The code `QApplication::instance()->setPalette` works with Qt 4, therefore I guess that the question has originally been asked actually for Qt 4. – Benjamin Bihler Oct 10 '19 at 05:30
  • @BenjaminBihler thanks for pointing this out, I have not used Qt 4 for ages. Probably the question is incorrectly tagged as qt5 – cbuchart Oct 10 '19 at 05:32
  • It's just a typo but as `QTimer::singleShot()` expects a value in _ms_ (and that you gave `1000`), it is not _"100ms"_ but _"1s"_ that you should output. – Fareanor Oct 10 '19 at 08:35
  • @Fareanor thanks, fixed! it was executed with 100ms but later changed for other experiment to 1s – cbuchart Oct 10 '19 at 10:21
  • No, it was not Qt4. From the Qt5 documentation: `The QApplication object is accessible through the instance() function that returns a pointer equivalent to the global qApp pointer.` – Zhigalin - Reinstate CMs Oct 11 '19 at 07:08
  • I think Qt's documentation (in the `instance()` section) is not completely explicit about the fact that there is a cast involved when using `qApp`, which is indeed mentioned in `qApp` part: https://doc.qt.io/qt-5.9/qapplication.html#qApp – cbuchart Oct 11 '19 at 07:18
  • Now I do remember, it really was qApp. Still, it's a documented behavior https://doc.qt.io/QT-5/qguiapplication.html#palette – Zhigalin - Reinstate CMs Oct 11 '19 at 08:27
  • Yes, but on the other hand the [`setPalette`](https://doc.qt.io/QT-5/qguiapplication.html#setPalette) is also documented to change the default palette, so basically I think default palette means default palette if widget doesn't specify the other one; not the default system palette – cbuchart Oct 11 '19 at 09:52
  • The problem was that setting the palette with setPalette() in one place worked (application colors actually changed) but using palette() in another place gave me the same old palette... – Zhigalin - Reinstate CMs Oct 17 '19 at 06:30
  • Maybe there is a second instance of QApplication that is overwriting the singleton? – cbuchart Oct 17 '19 at 06:39