Dark mode doesn't work well in Qt 6.5
-
Hi guys, I have the following problem, I have two buttons, one to change my app to dark mode and another to go back to a light style, the problem I have is that the title bar stays with the previous color, and it only changes if another operation is done, my question is how can I make the title bar of the form also change color, along with the entire app, thanks in advance.
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget), standarPalette{qApp->style()->standardPalette()} { ui->setupUi(this); QObject::connect(ui->pushButton, &QPushButton::clicked, this, [&](){ qApp->setPalette(standarPalette); }); QObject::connect(ui->pushButton_2, &QPushButton::clicked, this, [&](){ QPalette mPalette; mPalette.setColor(QPalette::Window, QColor(53, 53, 53)); mPalette.setColor(QPalette::WindowText, Qt::white); mPalette.setColor(QPalette::Base, QColor(25, 25, 25)); mPalette.setColor(QPalette::AlternateBase, QColor(53, 53, 53)); mPalette.setColor(QPalette::ToolTipBase, QColor(53, 53, 53)); mPalette.setColor(QPalette::ToolTipText, Qt::white); mPalette.setColor(QPalette::Text, Qt::white); mPalette.setColor(QPalette::PlaceholderText,QColor(127,127,127)); mPalette.setColor(QPalette::Button, QColor(53, 53, 53)); mPalette.setColor(QPalette::ButtonText, Qt::white); mPalette.setColor(QPalette::BrightText, Qt::red); mPalette.setColor(QPalette::Link, QColor(42, 130, 218)); mPalette.setColor(QPalette::Highlight, QColor(42, 130, 218)); mPalette.setColor(QPalette::HighlightedText, Qt::black); mPalette.setColor(QPalette::Disabled, QPalette::Text, QColor(164, 166, 168)); mPalette.setColor(QPalette::Disabled, QPalette::WindowText, QColor(164, 166, 168)); mPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(164, 166, 168)); mPalette.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(164, 166, 168)); mPalette.setColor(QPalette::Disabled, QPalette::Base, QColor(68, 68, 68)); mPalette.setColor(QPalette::Disabled, QPalette::Window, QColor(68, 68, 68)); mPalette.setColor(QPalette::Disabled, QPalette::Highlight, QColor(68, 68, 68)); qApp->setPalette(mPalette); qApp->setStyle("Fusion"); }); } Widget::~Widget() { delete ui; } #pragma once #include <QWidget> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr); ~Widget(); private: Ui::Widget *ui; const QPalette standarPalette{}; };
there you can see that the title bar stays with the previous color and changes after doing something else, such as changing the window or resizing the sale, or any other action and the colors when returning to light mode, are not the same as the default app had.
-
@lincoln said in Dark mode doesn't work well in Qt 6.5:
only changes if another operation is done, my question is how can I make the title bar of the form also change color, along with the entire app, thanks in advance.
What "other operation"?[Edit: Haven't seen the text below]such as changing the window or resizing
I assume it's because you need a full repaint/render of your window to change the title bar. The button might only refresh the widget's content.
-
@lincoln try this :
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget), standarPalette{qApp->palette()}
{
ui->setupUi(this);QObject::connect(ui->pushButton, &QPushButton::clicked, this, &{
qApp->setPalette(standarPalette);
});QObject::connect(ui->pushButton_2, &QPushButton::clicked, this, &{
QPalette mPalette;mPalette.setColor(QPalette::Window, QColor(53, 53, 53)); mPalette.setColor(QPalette::WindowText, Qt::white); mPalette.setColor(QPalette::Base, QColor(25, 25, 25)); mPalette.setColor(QPalette::AlternateBase, QColor(53, 53, 53)); mPalette.setColor(QPalette::ToolTipBase, QColor(53, 53, 53)); mPalette.setColor(QPalette::ToolTipText, Qt::white); mPalette.setColor(QPalette::Text, Qt::white); mPalette.setColor(QPalette::PlaceholderText,QColor(127,127,127)); mPalette.setColor(QPalette::Button, QColor(53, 53, 53)); mPalette.setColor(QPalette::ButtonText, Qt::white); mPalette.setColor(QPalette::BrightText, Qt::red); mPalette.setColor(QPalette::Link, QColor(42, 130, 218)); mPalette.setColor(QPalette::Highlight, QColor(42, 130, 218)); mPalette.setColor(QPalette::HighlightedText, Qt::black); mPalette.setColor(QPalette::Disabled, QPalette::Text, QColor(164, 166, 168)); mPalette.setColor(QPalette::Disabled, QPalette::WindowText, QColor(164, 166, 168)); mPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(164, 166, 168)); mPalette.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(164, 166, 168)); mPalette.setColor(QPalette::Disabled, QPalette::Base, QColor(68, 68, 68)); mPalette.setColor(QPalette::Disabled, QPalette::Window, QColor(68, 68, 68)); mPalette.setColor(QPalette::Disabled, QPalette::Highlight, QColor(68, 68, 68)); qApp->setPalette(mPalette); qApp->setStyle("Fusion");
});
}In this modified code, I'm setting the initial standarPalette to qApp->palette() to ensure that the palette is initially set to the default system palette.
Then, inside the dark mode button slot, I'm setting the QPalette::Window color to the same color as the QPalette::Base color. This should ensure that the title bar color changes along with the rest of the app.
-
@lincoln said in Dark mode doesn't work well in Qt 6.5:
I made the change you said but it doesn't work, now I don't go back to light mode anymore.
I apologize for the confusion. I made a mistake in my previous response. Instead of QApplication::setPalette, you should use QWidget::setPalette to set the palette for your main widget. QApplication::setPalette sets the palette for the entire application, including windows and dialogs, whereas QWidget::setPalette sets the palette only for the widget that you call it on.
try it now it should be executable :
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget), standardPalette{qApp->palette()}
{
ui->setupUi(this);QObject::connect(ui->pushButton, &QPushButton::clicked, this, &{
qApp->setPalette(standardPalette);
});QObject::connect(ui->pushButton_2, &QPushButton::clicked, this, &{
QPalette darkPalette;darkPalette.setColor(QPalette::Window, QColor(53, 53, 53)); darkPalette.setColor(QPalette::WindowText, Qt::white); darkPalette.setColor(QPalette::Base, QColor(25, 25, 25)); darkPalette.setColor(QPalette::AlternateBase, QColor(53, 53, 53)); darkPalette.setColor(QPalette::ToolTipBase, QColor(53, 53, 53)); darkPalette.setColor(QPalette::ToolTipText, Qt::white); darkPalette.setColor(QPalette::Text, Qt::white); darkPalette.setColor(QPalette::PlaceholderText,QColor(127,127,127)); darkPalette.setColor(QPalette::Button, QColor(53, 53, 53)); darkPalette.setColor(QPalette::ButtonText, Qt::white); darkPalette.setColor(QPalette::BrightText, Qt::red); darkPalette.setColor(QPalette::Link, QColor(42, 130, 218)); darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218)); darkPalette.setColor(QPalette::HighlightedText, Qt::black); darkPalette.setColor(QPalette::Disabled, QPalette::Text, QColor(164, 166, 168)); darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, QColor(164, 166, 168)); darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(164, 166, 168)); darkPalette.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(164, 166, 168)); darkPalette.setColor(QPalette::Disabled, QPalette::Base, QColor(68, 68, 68)); darkPalette.setColor(QPalette::Disabled, QPalette::Window, QColor(68, 68, 68)); darkPalette.setColor(QPalette::Disabled, QPalette::Highlight, QColor(68, 68, 68)); this->setPalette(darkPalette); qApp->setStyle("Fusion");
});
}Widget::~Widget()
{
delete ui;
} -
@lincoln said in Dark mode doesn't work well in Qt 6.5:
Could you show me some example or code of how to do it please.
Try a call of
update()
orrepaint()
on your window/widget.// at the end of your lambda this->update();
Or even do what is explained here.
But: use it with care. Depending on your app / app design, "just" updating all windows/widgets at once can be a very resource consuming task. Esp. when calling it frequently. -
A widget is only the underlying Qt representation without the window decoration (at least on some platforms). Try to get the underlying window first and update the window instead of just the widget.
-
@SimonSchroeder
Well, I don't understand what you mean by underlying window, and I have no idea how to do it, but thanks for your answer. -
@lincoln said in Dark mode doesn't work well in Qt 6.5:
Well, I don't understand what you mean by underlying window, and I have no idea how to do it, but thanks for your answer.
Qt has both QWidget and QWindow. The underlying operating system only knows about windows. However, creating each button, etc. as a window through the OS would be very slow. That is why Qt has a soft layer on top to quickly generate widgets instead of OS windows. The top level widgets still need to be windows.
Use https://doc.qt.io/qt-6/qwidget.html#windowHandle to get the underlying window if available. There, you can call
requestUpdate()
. -
@SimonSchroeder Hello friend, I tried to do what you mention, but when querying this->windowHandle();
the result is always a nullptr.