如何在 QtQuick Controls 2 的屏幕上居中显示对话框?

How to center dialog on screen in QtQuick Controls 2?

我所有的对话框都出现在屏幕的左上角而不是中心。

让对话框自动正确放置的最佳方法是什么?

import QtQuick 2.7
import QtQuick.Controls 2.2

ApplicationWindow {
    id: mainWindow

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

    Component.onCompleted: {
        showMessageBox('Hey this actually works!');
    }

    function showMessageBox(message) {
        var component = Qt.createComponent("MessageDialog.qml")
        if(component.status == Component.Ready) {
            var dialog = component.createObject(mainWindow)

            dialog.title = qsTr("Information")
            dialog.text = message

            dialog.open()
        } else
            console.error(component.errorString())
    }
}

用一个很简单的MessageDialog.qml:

import QtQuick 2.7
import QtQuick.Controls 2.2

Dialog {
    standardButtons: DialogButtonBox.Ok

    property alias text : textContainer.text

    Text {
        id: textContainer

        anchors.fill: parent

        horizontalAlignment: Qt.AlignLeft
        verticalAlignment: Qt.AlignTop
    }
}

文档提示,Dialog is a descendent of Popup which has x/y 坐标。

我认为这将是定位它的良好开端。

对你有用:

  • parent.width - 这应该是 window
  • 的宽度
  • width - 这应该是你的 Dialogs 宽度
  • parent.height
  • height

计算正确的位置,你应该没问题。

有了这个你可以创建一个新的基地class CenteredDialog.qml

Dialog {
    x: (parent.width - width) / 2
    y: (parent.height - height) / 2
}

然后一直使用 CenteredDialog 而不是 Dialog

此外,对于 动态实例化 ,您可以在文件中声明 Component,并且仅在实例化时使用 component.createObject(parentObject, { property1Name : property1Value, property2Name : property2Value ... }) 语法设置属性。

你可以设置x/y位置(像derM说的),但是你必须重新计算ApplicationWindow的每个大小变化!

这是另一个解决方案:

ApplicationWindow {
    id: mainWindow

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

    Component.onCompleted: {
        showMessageBox('Hey this actually works!');
    }

    Item {
        anchors.centerIn: parent
        width: msgDialog.width
        height: msgDialog.height
        MessageDialog {
            id: msgDialog
            title: qsTr("Information")
            visible: false
        }
    }

    function showMessageBox(message) {
        msgDialog.text = message
        msgDialog.visible = true
    }

更新:动态实例化:

 Item {
    id: dialogParent
    anchors.centerIn: parent
 }

 function showMessageBox(message) {
    var component = Qt.createComponent("MessageDialog.qml")
    if(component.status === Component.Ready) {
        var dialog = component.createObject(dialogParent)

        dialog.title = qsTr("Information")
        dialog.text = message
        dialog.open()

        dialogParent.width = dialog.width
        dialogParent.height = dialog.height
    } else {
        console.error(component.errorString())
    }
 }

对于适用于任何地方(包括 Window/ApplicationWindow 之外)的通用代码,您应该使用 Overlay parent :

Dialog {
    parent: Overlay.overlay // <------- global Overlay object
    readonly property int margin: 16
    width: parent ? (parent.width / 2 - margin) : 128
    height: content.height + margin
    x: parent ? ((parent.width - width) / 2) : 0
    y: parent ? ((parent.height - height) / 2) : 0
    modal: true

   Label {
      id: content
      ...   
   }
}

从 Qt 5.12 开始,您可以使用 anchors.centerIn 附加的 属性。

Dialog {
    anchors.centerIn: parent
    // ...
}

然后它将以其父级为中心。如果您希望它以 window 为中心,只需将其父级设置为 Overlay.overlay.