Как сделать немодальное диалоговое окно всегда сверху?

Я использую экземпляр Dialog {} в моем приложении для отображения небольшого окна контроллера, с которым пользователь может взаимодействовать, чтобы повлиять на функции в главном окне (вид пульта дистанционного управления). Я могу сделать этот диалог модальным (modality: Qt.WindowModal или modality: Qt.ApplicationModal) или я могу сделать его немодальным с modality: Qt.NonModal.

моя проблема в том, что мне нужно сделать его немодальным, но всегда быть поверх главного окна. Если я использую Qt.NonModal Я все еще могу нажать на основную форму, но затем мой диалог идет за ней. Этот Dialog класс не кажется flags: собственность, поэтому я не могу просто установить его в Qt.WindowsStaysOnTopHint.

есть ли способ установить флаги диалога, подобного этому, исключительно со стороны QML? Или можно написать простой метод утилиты на c++, который я мог бы вызвать изComponent.onCompleted: и пройти в диалоговом окне, чтобы установить его флаги windows там?

Update: чтобы проиллюстрировать, о чем я говорю, вот мой диалог поверх моего основного окно:

enter image description here

вот мой диалог под моим главным окном:

enter image description here

Я хочу, чтобы мой диалог не проходил под моим главным окном, но я все равно хочу иметь возможность нажимать и взаимодействовать с моим главным окном. Другими словами, Я хочу, чтобы мой диалог был немодальным, но всегда сверху.

3 ответов


попробуйте использовать Window вместо Dialog таким образом, у вас будет доступ к flags собственность.

вы можете установить flags to Qt.WindowStaysOnTopHint чтобы ваше окно всегда поверх остальных. Вы можете найти список флагов здесь. (Не забудьте заменить :: by . в 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


хорошо, поэтому вы просто хотите создать диалог (или компонент, который выглядит как диалог) и просто хотите взаимодействовать с главным окном и диалоговое окно.

пожалуйста, попробуйте следующее:

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
        }
    }

}

обычно вы хотите использовать Dialog не только для создания нового окна, но и для его реализованной функциональности и интерфейса...

причина в том, что Dialog не наследует Window или ApplicationWindow очевидно: нет окна, пока его нет open(). Но как только он открыт, есть ApplicationWindow (от Наш QtQuick.Управления 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 который остается сверху, но не является модальным.