Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I toggle 'always on top' for a QMainWindow in Qt without causing a flicker or a flash?

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?

like image 618
Jake Petroules Avatar asked May 18 '10 09:05

Jake Petroules


2 Answers

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.

like image 136
HostileFork says dont trust SE Avatar answered Sep 21 '22 13:09

HostileFork says dont trust SE


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 } 
like image 33
Jake Petroules Avatar answered Sep 21 '22 13:09

Jake Petroules