2017-07-06 192 views
5

我在我的应用程序中使用Dialog {}的一个实例来显示一个小的控制器窗口,用户可以通过这个窗口进行交互以影响主窗口中的功能(排序遥控器)。我可以制作这个对话框模式(modality: Qt.WindowModalmodality: Qt.ApplicationModal),或者我可以用modality: Qt.NonModal使它成为非模态。如何使非模态对话框始终位于顶部?

我的问题是,我需要使它非模态,但始终在主窗口的顶部。如果我使用Qt.NonModal,我仍然可以点击主窗体,但是随后我的对话框会出现在它后面。 Dialog类似乎没有flags:属性,所以我不能将它设置为Qt.WindowsStaysOnTopHint

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

更新:说明一下我说的,这是我在我的主窗口顶部的对话框:

enter image description here

这里是我的对话我的主窗口下方:

enter image description here

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

+0

也许你可以用MouseArea过滤掉对话外的点击事件? – sk2212

+0

@ sk2212:我认为这不会起作用。我希望使用它能够点击并与主窗口或浮动远程进行交互。基本上只是标准的工具窗口行为。 – MusiGenesis

+0

嗯......你可以从你的窗口和对话框创建一个简单的截图吗?我仍然不明白你的观点。 – sk2212

回答

4

尝试使用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

+0

所以我以前的使用Window的尝试在'createComponent'(这是关于不存在的标志和模态属性的错误)上莫名其妙地失败了,但是当我根据您的示例创建了一个新类时,Window完美地工作。我正在开发的应用程序是从其他开发人员继承而来的代码库,他们似乎在C++中添加了一些神奇的底层代码,它们用QML自带的版本替换了真正的Window类暴露标志和形式,因此错误)。一旦我在我的课堂上评论他们的进口陈述,“窗口”的作品... – MusiGenesis

+2

...完美的,非模态的,总是在我的主窗口之上。有时我讨厌我的开发人员,但是*你*我喜欢。我要为这个问题添加一个奖励(我将会为此付出一定的奖励,以帮助我获得答案)。 – MusiGenesis

0

好的,你只需要创建一个对话框(或者看起来像一个对话框的组件),并且只想与主窗口交互对话框窗口。

请尝试以下方法:

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”文件以适合您自己的设计要求。

但是,使用此作为一个“真正的”对话也没有工作,(我)像通用已经在评论部分中指出:

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

我想我没有传达我想要做的事。我可以很容易地在你的答案中做你正在做的事情 - 在我的主窗口中间弹出一个矩形,并与它或下面的窗口进行交互。这只是标准的QML布局。我试图用一个单独的窗口来实现这一点 - 这是你的DialogQt.qml也不能实现的,因为它是模态的(我需要一个单独的窗口,它是非模态的,但总是在我的主窗口的顶部)。 – MusiGenesis

+0

@MusiGenesis你必须使用'Dialog'吗?是使用'Window'而不是工作?我在我的应用程序中用'Window'完成了完全相同的事情(非模态但始终在顶部)。 – Blabdouze

+0

@Blabdouze:我之前尝试过使用'Window'而不是'Dialog',但是'createComponent'调用保持失败,并且在Window上没有像'flags:'或'modality:'这样的属性,我将不得不设置这个工作(我假设)。我在Qt 5.5,也许这是我的问题?你能用'Window'发表一个答案吗? – MusiGenesis

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保持在顶部,但不是模态。

相关问题