如何在Qt中为QMainWindow切换"always on top"而不会引起闪烁或闪烁?

Jak*_*les 22 c++ qt window-managers

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的解决方案有效,但因为setWindowFlags隐藏了窗口,所以需要重新显示它,当然看起来并不优雅.那么如何在没有"闪烁"副作用的情况下为QMainWindow切换"永远在线"?

Hos*_*ork 19

诺基亚说没有:

一旦创建窗口,就不可能对窗口标志进行更改而不会引起闪烁.由于需要重新创建窗口,因此闪烁是不可避免的.

但有时如果你遇到像这样丑陋的闪光效果,你可以故意将其拖出来让它看起来像刚刚发生的"酷".

也许弹出一个不在窗口中的小进度条,说"调整窗口属性!"......将窗口淡出存在然后重新进入,然后关闭进度条弹出窗口.

  • 对于"始终在线"功能,这必须是可能的.很多应用程序都没有闪烁; 也许我只需要使用一些原生的Windows功能? (2认同)

Jak*_*les 16

好吧,对于一个解决方案,我认为我会查看Mono源代码,因为我知道.NET Form类(System.Windows.Forms)具有TopMost属性.

我在Qt程序中找到的解决方案是:

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
}
Run Code Online (Sandbox Code Playgroud)

  • 答案是正确的,但是对于 Qt5,需要将 `reinterpret_cast` 添加到 `HWND` 中的 `this-&gt;winId()` (2认同)