如何使非模态对话窗口始终位于顶部?

时间:2017-07-06 13:57:51

标签: qt qml

我在我的应用程序中使用Dialog {}的实例来显示一个小的控制器窗口,用户可以与之交互以影响主窗口中的功能(一种遥控器)。我可以制作这个对话模式(modality: Qt.WindowModalmodality: Qt.ApplicationModal),或者我可以使用modality: Qt.NonModal使其成为非模态。

我的问题是我需要将其设为非模态但始终位于主窗口的顶部。如果我使用Qt.NonModal我仍然可以点击主表单,然后我的对话框就可以了。 Dialog类似乎没有flags:属性,因此我无法将其设置为Qt.WindowsStaysOnTopHint

有没有办法像QML那样设置像这样的Dialog标志?或者是否可以在c ++中编写一个简单的实用程序方法,我可以从我的对话框Component.onCompleted:调用它并传入对话框以在那里设置它的窗口标志?

更新:为了说明我在谈论的内容,这是我在主窗口顶部的对话框:

enter image description here

这是我的主窗口下面的对话框:

enter image description here

我希望我的对话框不要像我这样在我的主窗口下面,但我仍然希望能够点击并与我的主窗口进行交互。换句话说,我希望我的对话框是非模态的,但总是在顶部。

3 个答案:

答案 0 :(得分:7)

尝试使用Window代替Dialog,这样您就可以访问flags属性。

您可以将flags设置为Qt.WindowStaysOnTopHint,让您的窗口始终位于其他窗口之上。您可以找到标志列表here。 (不要忘记在QML中用::替换.

Main.qml:

import QtQuick 2.5
import QtQuick.Controls 2.0
import QtQuick.Dialogs 1.2

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")


    Button {
        id: btn
        width: 100 ; height : 40
        text: "click me"
    }

    Text {
        anchors.top : btn.bottom
        text: "Button currently pressed"
        visible: btn.pressed
    }

    DialogOnTop {

    }
}

DialogOnTop.qml:

import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 1.4

Window {
    id: myWindow

    width: 200
    height: 200

    flags:  Qt.Window | Qt.WindowSystemMenuHint
            | Qt.WindowTitleHint | Qt.WindowMinimizeButtonHint
            | Qt.WindowMaximizeButtonHint | Qt.WindowStaysOnTopHint


    visible: true
    modality: Qt.NonModal // no need for this as it is the default value


    Rectangle {
        color: "lightskyblue"
        anchors.fill: parent
        Text {
            text: "Hello !"
            color: "navy"
            anchors.centerIn: parent
        }
    }
}

结果:

always on top window

答案 1 :(得分:0)

好的,所以你只想创建一个Dialog(或一个看起来像Dialog的组件),只想与主窗口对话窗口进行交互。

请尝试以下方法:

main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0

ApplicationWindow {
    id: rootWindow
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    color: "green"

    Rectangle {
        id: behind
        anchors.fill: parent
        color: Qt.rgba(0, 0, 0,  0.7)
        visible: false
    }

    MouseArea {
        enabled: behind.visible
        anchors.fill: parent

        onClicked: {
            console.log("Root Window")
        }
    }

    Button {

        text: "Open Dialog"

        onClicked: {
            behind.visible = true;
            var comp = Qt.createComponent("qrc:/MyDialog.qml");
            // var comp = Qt.createComponent("qrc:/DialogQt.qml");
            var obj1 = comp.createObject(rootWindow, {});
            obj1.z = 2;
        }
    }
}

MyDialog.qml

import QtQuick 2.7

Rectangle {
    id: modalWindow
    width: 200
    height: 200
    color: "red"

    anchors.centerIn: parent

    MouseArea {
        anchors.fill: parent
        onClicked: {
            console.log("Modal Window")
        }
    }
}

单击“打开对话框”按钮将创建并打开主窗口组件顶部的“模态”对话框。

当然,您必须自行调整“MyDialog.qml”文件以满足您的设计要求。

然而,使用它作为“真正的”对话对我来说也是有用的,就像G.M已经在评论部分指出的那样:

DialogQt.qml

Dialog {
    visible: true
    title: "Blue sky dialog"

    modality : Qt.ApplicationModal

    contentItem: Rectangle {
        color: "lightskyblue"
        anchors.fill: parent
        Text {
            text: "Hello blue sky!"
            color: "navy"
            anchors.centerIn: parent
        }
    }

}

答案 2 :(得分:0)

通常你想使用Dialog不只是为了创建一个新窗口,而是为了它实现的功能和界面......

Dialog未继承WindowApplicationWindow的原因显而易见:没有窗口,只要它不是open()。但是一旦打开,就会有一个ApplicationWindow(来自QtQuick.Controls 1.4)

现在,在文档中我们找到了这个很好的attatched属性:ApplicationWindow,每个Item都可以使用它,方便它允许我们访问窗口。然后我们只需找到一种方法,一旦ApplicationWindow变得可用,就设置正确的标志 - 例如当我们得到信号visibleChanged时 由于Dialog也不是Item,我们需要使用其contentItem来访问此附加属性。

当我们将所有这些放在一起时,结果可能如下所示:

NonModalDialogThatStaysOnTop.qml //我很难命名

import QtQuick 2.3
import QtQuick.Controls 1.4 // You need this, to have access to the `ApplicationWindow`-attatched property
import QtQuick.Dialogs 1.2

Dialog {
    onVisibleChanged: {
        if (visible) contentItem.ApplicationWindow.window.flags |= Qt.WindowStaysOnTopHint
    }
    modality: "NonModal"
}

现在,你最喜欢的Dialog保持在最顶层,但不是模态的。