void MainWindow::on_actionAlways_on_Top_triggered(bool checked) { Qt::WindowFlags flags = this->windowFlags(); if (checked) { this->setWindowFlags(flags | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint); this->show(); } else { this->setWindowFlags(flags ^ (Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint)); this->show(); } }
The above solution works but because setWindowFlags hides the window, it needs to be re-shown and of course that doesn't look very elegant. So how do I toggle "always on top" for a QMainWindow without that "flashing" side effect?
Nokia says no:
It is not possible to make changes to the window flags once the window has been created without causing flicker. Flicker is unavoidable since the window needs to be recreated.
But sometimes if you're stuck with a flashing effect that's kind of ugly like this, you can intentionally drag it out to make it seem like something "cool" just happened.
Maybe pop up a little progress bar that's not in the window, say "Adjusting Window Properties!"...fade the window out of existence and then back in, and close the progress bar popup.
Well, for a solution I figured I'd look in the Mono sources, since I know the .NET Form class (System.Windows.Forms) has a TopMost property.
The solution I found for my Qt program was:
void MainWindow::on_actionAlways_on_Top_triggered(bool checked) { #ifdef Q_OS_WIN // #include <windows.h> if (checked) { SetWindowPos(this->winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); } else { SetWindowPos(this->winId(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); } #else Qt::WindowFlags flags = this->windowFlags(); if (checked) { this->setWindowFlags(flags | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint); this->show(); } else { this->setWindowFlags(flags ^ (Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint)); this->show(); } #endif }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With