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

时间:2017-07-12 07:43:05

标签: qt qml qt5 qtquick2 qtquickcontrols2

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

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

enter image description here

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

4 个答案:

答案 0 :(得分:7)

文档提示,Dialog是[{3}}的后代,其Popup - 坐标。

我认为这将是一个良好的开端。

为了你的利益:

  • parent.width - 应该是窗口的宽度
  • width - 应该是您的Dialog宽度
  • parent.height
  • height

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

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

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

然后始终使用CenteredDialog代替Dialog

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

答案 1 :(得分:3)

您可以设置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())
    }
 }

答案 2 :(得分:2)

对于适用于任何地方(包括不在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
      ...   
   }
}

答案 3 :(得分:1)

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

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

然后它将在其父对象中居中。如果希望它在其窗口中居中,只需将其父项设置为Overlay.overlay