2017-07-06 188 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保持在頂部,但不是模態。

相關問題