【问题标题】:How to make Qt Application mainwindow to remain always on top of other windows in Windows OS?如何使 Qt 应用程序主窗口始终保持在 Windows 操作系统中的其他窗口之上?
【发布时间】:2016-11-24 13:18:18
【问题描述】:

平台 - Windows 7、8、10

我从 QMainWindow 创建了一个 QApplication。 我希望它始终位于所有其他窗口之上。

我使用 Qt 标志 ( Qt::WindowStaysOnTopHint ) 来实现这一点。 但是这个 Qt 标志不起作用。 该应用程序是无框架应用程序。

请在下面找到我的 Qt App 的构造函数代码。

myApp::myApp(QWidget *parent)
: QMainWindow(parent)
{
setWindowFlags(Qt::Widget |  Qt::FramelessWindowHint);
setWindowFlags(this->windowFlags() | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint );
ui.setupUi(this);
}

我怎样才能使这个标志起作用?

我已经尝试了几个社区成员建议的所有选项。 我现在的代码如下

Qt::WindowFlags flags = this->windowFlags();
this->setWindowFlags(flags  | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
ui.setupUi(this);

奇怪的事实是这在我的机器上从来没有用过。 当我创建安装程序或复制所需文件并在不同的机器(Windows 7、8、10)上运行时,我的应用程序将位于所有其他窗口之上。 注意:我使用的是 Visual Studio Community Edition 2015 操作系统 - Windows 7 Professional Service Pack 1。

【问题讨论】:

    标签: qt qt5.6


    【解决方案1】:

    在构造函数中写一行简单的代码。 (无需包含任何其他标题)

    setWindowFlag(Qt::WindowStaysOnTopHint);
    

    【讨论】:

      【解决方案2】:

      以下代码终于让我的窗口始终高于其他窗口

      SetForegroundWindow((HWND)winId());
      Qt::WindowFlags flags = this->windowFlags();
      flags = flags & ~Qt::WindowMinimizeButtonHint;
      this->setWindowFlags(flags|Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint );
      ui.setupUi(this);
      

      我还通过取消设置最小化标志来阻止窗口的最小化选项。 但仍然存在一个问题。窗口的下部越过任务栏。我必须单击应用程序图标才能将下半部分带到任务栏上方。

      【讨论】:

      • 另外我想补充一下,您需要包含“windows.h”才能使用 SetForegroundWindow()
      【解决方案3】:

      你必须在ui.setupUi(this);之后设置setWindowFlags

      【讨论】:

      • 我也试过这个选项。我尝试过的所有建议都不适用于我的机器,但在其他机器上运行良好。
      【解决方案4】:

      使窗口位于所有应用程序之上。

      myApp.h

          class myApp: public QMainWindow
          {
              Q_OBJECT
              public:
              explicit myApp(QWidget *parent = 0);
              ~myApp();
          protected:
              bool event(QEvent *event);
              ----
          };
      

      myApp.cpp

      #include <windows.h>
      #include <winuser.h>    
      myApp::myApp(QWidget *parent): QMainWindow(parent)
      {
          setWindowFlags(Qt::FramelessWindowHint |Qt::WindowStaysOnTopHint);
          ui.setupUi(this);
      }
      bool myApp::event(QEvent *event){
          switch (event->type())
          {
          case QEvent::Show:
          {
              HWND winHWND =(HWND) winId();
              if( winHWND ){
                  qDebug() << endl << "Setting up associated console window ON TOP !";
                  SetWindowPos(
                              winHWND, // window handle
                              HWND_TOPMOST, // "handle to the window to precede
                              // the positioned window in the Z order
                              // OR one of the following:"
                              // HWND_BOTTOM or HWND_NOTOPMOST or HWND_TOP or HWND_TOPMOST
                              0, 0, // X, Y position of the window (in client coordinates)
                              0, 0, // cx, cy => width & height of the window in pixels
                              SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW // The window sizing and positioning flags.
                              );
                  // OPTIONAL ! - SET WINDOW'S "SHOW STATE"
                  ShowWindow(
                              winHWND, // window handle
                              SW_NORMAL // how the window is to be shown
                              // SW_NORMAL => "Activates and displays a window.
                              // If the window is minimized or maximized,
                              // the system restores it to its original size and position.
                              // An application should specify this flag
                              // when displaying the window for the first time."
                              );
                  qDebug() << endl << "Done.";
              } else {
                  qDebug() << endl << "There is no console window associated with this app :(";
              }
              break;
          }
          default:
              break;
          }
      
          return QMainWindow::event(event);
      }
      

      For more help

      【讨论】:

      • 我已经尝试过您的解决方案。我也尝试过其他答案。没有什么适合我。有时我将窗口作为最顶层的窗口,有时我没有。有什么办法可以调试标志出了什么问题?
      【解决方案5】:

      见:

      http://doc.qt.io/qt-5/qt.html http://doc.qt.io/qt-5/qtwidgets-widgets-windowflags-example.html

      使用 WindowStaysOnTopHint 标志。来自 Qt 文档:

      "通知窗口系统该窗口应该保持在所有的顶部 其他窗口。请注意,在 X11 上的某些窗口管理器上,您也有 传递 Qt::X11BypassWindowManagerHint 以使该标志起作用 正确。”

      您的错是您分别为 FramelessWindowHint 和 WindowStaysOnTopHint 调用了两次 setWindowFlags。试试:

         Qt::WindowFlags flags = windowFlags();
         setWindowFlags(flags | Qt::X11BypassWindowManagerHint |     Qt::WindowStaysOnTopHint);
      

      或者您可以使用 Windows 系统 API:

      #include <Windows.h>
      ....
      
      SetForegroundWindow((HWND)winId());
      setWindowFlags(Qt::WindowStaysOnTopHint);
      

      在您的 .pro 文件中:

      win32-g++:LIBS += libUser32
      win32-msvc*:LIBS += User32.lib
      

      【讨论】:

      • 我已经尝试过您的解决方案。有时它有效,有时则无效。我不知道为什么它有时不起作用。
      猜你喜欢
      • 2011-01-27
      • 1970-01-01
      • 2016-04-01
      • 2011-03-20
      • 1970-01-01
      • 1970-01-01
      • 2013-01-30
      • 2017-12-03
      • 1970-01-01
      相关资源
      最近更新 更多