How to make a modeless dialog box always on top?

I am using an instance of Dialog {} in my application to display a small controller window with which the user can interact to influence the functions in the main window (a type of remote control). I can make this dialog modal ( modality: Qt.WindowModal or modality: Qt.ApplicationModal ), or I can make it non-modal with modality: Qt.NonModal .

My problem is that I need to make it modeless, but always be at the top of the main window. If I use Qt.NonModal , I can still click on the main form, but then my dialog is behind. The Dialog class does not have the flags: property, so I cannot just set it to Qt.WindowsStaysOnTopHint .

Is there a way to set the dialog flags the way it does with QML? Or can you write a simple utility method in C ++, which I could call from my dialog Component.onCompleted: and pass in a dialog box to set Windows flags there?

Update: To illustrate what I'm talking about, here is my dialogue on top of my main window:

enter image description here

Here is my dialogue under my main window:

enter image description here

I want my dialog not to fall under my main window like this, but I still want to be able to click and interact with my main window. In other words, I want my dialogue to be modeless, but always on top.

+5
source share
3 answers

Try using Window instead of Dialog so you have access to the flags property.

You can set flags to Qt.WindowStaysOnTopHint so that your window is always on top of others. You can find a list of flags here . (Remember to replace :: with . In 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 } } } 

Result:

always in the top window

+4
source

So, you just want to create a dialog (or a component that looks like a dialog) and just want to interact with the main window and the dialog box.

Try the following:

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

Clicking the Open Dialog button will create and open the modal dialog box at the top of the main window component.

Of course, you need to customize the "MyDialog.qml" file to suit your design requirements.

However, using this as a β€œreal” dialog also works (for me), as indicated in the comments section in G.MM:

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

Usually you want to use Dialog not only to create a new window, but also for its implemented functions and interface ...

The reason Dialog does not inherit Window or ApplicationWindow is obvious: there is no window if it is not open() . But once it is open, there is ApplicationWindow (from QtQuick.Controls 1.4)

Now in the documentation we find this nice property attatched: ApplicationWindow , which is available for each Item , and conveniently it allows us to access the window. Then we just need to find a way to set the correct flags as soon as ApplicationWindow becomes available - for example. when we get the visibleChanged signal.
Since Dialog not equal to Item , we must use its contentItem to access this attached property.

When we put it all together, the result may look like this:

NonModalDialogThatStaysOnTop.qml // I suck the naming convention

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

Now you have your favorite Dialog , which remains on top, but is not modal.

0
source

Source: https://habr.com/ru/post/1269565/


All Articles