2010-05-18 121 views
20
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(); 
    } 
} 

上述解決方案的工作原理,但因爲setWindowFlags隱藏窗口,它需要重新顯示,當然,看起來不是很優雅。那麼如何在沒有「閃爍」副作用的情況下爲QMainWindow切換「永遠在最前面」?如何在Qt中爲QMainWindow切換'always on top'而不會導致閃爍或閃爍?

回答

19

諾基亞says no

這是不可能的,一旦窗口已不會產生閃爍創建更改窗口標誌。由於窗口需要重新創建,閃爍是不可避免的。

但有時,如果你堅持一個閃爍的效果有點難看這樣,你可以故意將其拖出,使之看起來像什麼「酷」就這樣發生了。

也許彈出一個小的進度條,這不是在窗口,說「調整窗口屬性!」 ......淡出窗口不存在了,然後回來,並關閉進度條彈出。

+7

+1:對於好 「解決方法」 的想法;) – ereOn 2010-05-18 09:46:35

+2

對於「始終在上」功能,這必須是可能的。大量的應用程序沒有閃爍;也許我只需要使用一些本地Windows功能? – 2010-05-18 09:47:26

+1

如果您想要在Qt實現之下(或摧毀窗口並重新創建它),那麼可能會出現這種情況。但至少有一些是「Window Class」IIRC的屬性,而不是HWND;並且您可能無法在創建後更改窗口的類。無論哪種方式,我認爲在不打破Qt抽象層的情況下提出可以接受的答案的價值要好於在Win32黑客中陷入困境。這就是Qt的喜悅... – HostileFork 2010-05-18 09:58:42

14

那麼,對於一個解決方案,我想我會看在單聲道音源,因爲我知道.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 
} 
+0

如果你真的認爲它是值得的(!)但是我建議至少把它作爲一個單獨的方法分解出來。 * void setWindowStaysOnTopHint(bool windowStaysOnTopHint)*。那麼你的ifdef不會跨越你的按鈕,它會更準確地反映出你「想要」的例程,如果你爲所有平臺提交了補丁,諾基亞可能會在某一天添加​​。在那個例程中,我也一定要留下一個鏈接到這個SO問題,所以有人想知道爲什麼它會在那裏找到... – HostileFork 2010-05-18 21:21:39

+1

我已經這樣做了,在一個單獨的類中有幾個方法來處理它。如果其他人看過這個問題,我只是爲了方便而在這裏發佈它。 提交給諾基亞的有趣想法,但是,我一定會考慮一旦我實施工作碳和X11解決方案。 – 2010-05-18 21:43:08

+1

答案是正確的,但是對於Qt5,需要將'reinterpret_cast'添加到'HWND'中以獲得'this-> winId()' – Predelnik 2015-05-26 08:09:09

-1

在Windows XP

  • 測試與

    • 的Qt 5.2.1 Qt的5.2 OS X 10.9
     
    
        void ConsoleUI::onAllwaysTop(bool checked) 
        { 
         Qt::WindowFlags flags = windowFlags(); 
         if (checked) 
         { 
          flags ^= Qt::WindowStaysOnBottomHint; 
          flags |= Qt::WindowStaysOnTopHint; 
         } 
         else 
         { 
          flags ^= Qt::WindowStaysOnTopHint; 
          flags |= Qt::WindowStaysOnBottomHint; 
         } 
         setWindowFlags(flags); 
         show(); 
        } 
    
    
  • +2

    這是完全錯誤的。首先它將窗口設置爲*永遠在底部*,這幾乎是你永遠不會想要的(當然在這個問題上並不需要)。其次,它不回答*如何做到沒有閃爍*的問題。 – Timmmm 2014-11-27 14:37:37