Windows上的QML:让窗口保持最佳状态

时间:2017-02-16 12:00:09

标签: windows qml

我确实需要让我的窗口在Windows上保持最佳状态,但Windows本身似乎没有willing to allow me这样做。

我无法使用解决方法来设置注册表值,因为我无法要求用户注销/登录。

此外,我使用QML并且QWidget::raise() and QApplication::setActiveWindow()的解决方案似乎也不起作用,因为我没有设法使用以下代码将QML根对象作为QWidget指针获取:

QWidget* mainWin = qobject_cast<QWidget*>(engine.rootObjects().at(0));
if (mainWin)
{
    mainWin->raise();
    QApplication::setActiveWindow(mainWin);
    mainWin->activateWindow();
}

我还尝试从QML中激活窗口:

window.raise()
window.requestActivate()

但也没有运气。

是否有任何方法可以在不更改注册表的情况下将窗口置于Windows顶部,最好是纯粹来自QML?

修改: 目前使用的窗口标志是:

Qt.Popup
Qt.FramelessWindowHint
Qt.WindowStaysOnTopHint
Qt.CustomizeWindowHint
Qt.BypassWindowManagerHint
Qt.MSWindowsFixedSizeDialogHint

我正在Windows 10 x64 计算机上部署 Qt 5.7应用。 我发现了这两个错误修正:

我可以从中得出结论,QWidget :: activateWindow()和QWindow :: requestActive()应该可以在Windows XP和Windows 7上运行。

这是我的 mcve ,正如@derM问的那样:

import QtQuick 2.7
import QtQuick.Window 2.2

Window {
    flags: Qt.WindowStaysOnTopHint

    width: 100
    height: 100
    visible: true
}

它是在Windows 10 x64下使用MinGW x32编译的。

更容易重现:在命令提示符下运行

timeout 5 && debug\Test.exe

其中debug \ Test.exe是mcve二进制文件的路径,然后打开文件资源管理器并导航到某处。当窗口打开时,它不会在前台。

更难的方式:如果您只是运行它,窗口将保持在应有的顶部。 但是,如果您按下Qt Creator中的“运行”按钮并切换焦点(我想,应该更改鼠标焦点,只需按Alt + Tab即可获得帮助)到另一个进程(在我的情况下 - 文件资源管理器),将显示窗口在当前活动的文件资源管理器窗口下,即使我点击它,它也会在我选择任何其他应用程序后立即显示。

真正的应用程序是从服务启动的,因此在我的应用程序启动时,通常会有一个应用程序保持鼠标焦点。我认为Qt将窗口置于前台的能力是使用SetForegroundWindow API调用实现的,该调用在注释中注明了以下限制:

  • 该过程是前台过程。
  • 该过程由前台进程启动。
  • 该过程收到了最后一个输入事件。
  • 没有前台进程。
  • 正在调试该过程。
  • 前台进程不是现代应用程序或开始屏幕。
  • 未锁定前景(请参阅LockSetForegroundWindow)。
  • 前台锁定超时已过期(请参阅 - SystemParametersInfo中的SPI_GETFOREGROUNDLOCKTIMEOUT)。
  • 没有菜单处于活动状态。

所以我想知道如果进程已经由服务而不是用户启动(例如,启动期间进程不是活动进程),可以将窗口置于前台。

1 个答案:

答案 0 :(得分:3)

正如您所发布的:如果窗口是从前台进程创建的,我们将确保在创建窗口之前我们的进程是前台进程。

import QtQuick 2.7
import QtQuick.Window 2.2

Item {
    id: root

    Component { // Like a splash screen: Claim to be foreground process,
                // then create main window.
        id: winInit
        Window {
            flags: Qt.WindowStaysOnTopHint
            width: 1
            height: 1
            Component.onCompleted: {
                requestActivate()
                mainWin.createObject(root)
            }
        }
    }

    Component {
        id: mainWin
        Window {
            flags: Qt.WindowStaysOnTopHint
            width: 100
            height: 100
            visible: true
        }
    }

    Component.onCompleted: {
        var w1 = winInit.createObject(null)
        w1.destroy()
    }
}