显示对话框 onCompleted 无法按预期工作

Posted

技术标签:

【中文标题】显示对话框 onCompleted 无法按预期工作【英文标题】:Showing a Dialog onCompleted doesn't work as expected 【发布时间】:2015-09-13 18:28:25 【问题描述】:

我想在某些条件下显示DialogonCompleted(此处省略处理此条件 - 一个简单的if 子句)

main.qml:

import QtQuick 2.2
import QtQuick.Controls 1.0

ApplicationWindow

    id: appWindow

    width: 480
    height: 640
    visible: true


    StackView
    
        id: stackView
        anchors.fill: parent
        // Implements back key navigation
        focus: true

        initialItem: Item
        
            width: parent.width
            height: parent.height
            Button  onClicked: dialog.open() 
            // ...
            Component.onCompleted: dialog.open()
        
    

    MyDialog id: dialog 

MyDialog.qml

import QtQuick 2.0
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.0
import QtQuick.Controls 1.0

Dialog

    id: root

    title: "MyDialog"
    standardButtons: Qt.NoButton

    ColumnLayout
    
        id: column
        width: parent ? parent.width : 200
        Label  text: "hello world"; Layout.fillWidth: true 
    

当我启动我的应用程序时,屏幕变暗,Dialog 的阴影出现,好像对话框有width == 0

有时(很少)对话框会正确显示。

如果我注释掉Component.onCompleted 行并使用Button 启动对话框,它会正确显示。

我做错了什么? 我正在使用适用于 android 的 Qt 5.5

【问题讨论】:

【参考方案1】:

如果在窗口具有健全的几何形状之前打开对话框,则无法正常打开对话框。

一个安全的选择是使用onWidthChanged 信号

main.qml

import QtQuick 2.2
import QtQuick.Controls 1.0

ApplicationWindow

    id: appWindow

    width: 480
    height: 640
    visible: true


    StackView
    
        id: stackView
        anchors.fill: parent
        // Implements back key navigation
        focus: true

        initialItem: Item
        
            property bool firstTime: true
            width: parent.width
            height: parent.height
            // ...
            // width may be called multiple times
            onWidthChanged: if (firstTime) firstTime = true; dialog.open()
        
    

    MyDialog id: dialog 

【讨论】:

【参考方案2】:

请参考Dialog QML Type的官方文档,在那里你可以找到下一个:

注意:不要尝试将对话框的宽度或高度绑定到 其内容的宽度或高度,因为 Dialog 已经尝试调整大小 本身的内容。如果您的目标是改变或消除 边距,您必须覆盖 contentItem。如果你的目标只是展示 一个窗口(无论是否模式),并且您的平台支持它,它是 改用 Window 更简单。

因此,在您的情况下,最好以某种方式隐式设置内部元素的宽度。另一种快速的解决方案是添加(例如)具有给定宽度的Rectangle 元素作为对话框的一个内部根元素。您可以在此 Rectangle 中放置其他元素。

【讨论】:

只有当我启动对话框 onCompleted 时才会出现问题(请参阅更新的 OP)。 Qt 示例本身建议将width 设置为parent.width,参见doc.qt.io/qt-5/… 首先,你是对的——原始示例中的有趣点。其次,它是 QML -> IMO,永远无法 100% 确定。这是从文档中引用到(组件)[doc.qt.io/qt-5/qml-qtqml-component.html]:>相应的处理程序是onCompleted。它可以在任何对象上声明。 onCompleted 处理程序的运行顺序是未定义。只是一个测试说明——尝试在 StackedView depth 更改上触发 dialog.open() 是的,就是这样。我发布了一个我制定的解决方案。使用Stack.status 附加属性甚至比使用depth 更有效。如果您有更好的想法,请发布。 不,我没有更好的主意。看来你的解决方法没问题。 使用Stack.status 并不总是有效。我刚刚发现了:(【参考方案3】:

我发布另一个答案,因为它是另一种方法。我记得我是如何在一些旧项目上实现它的。 AFAIK,目前这是最好的方法。 如果有人提供更好的解决方案,我会很高兴

您需要添加一个中间元素,例如Timer。这个计时器(tm 在下面的代码中)必须有小间隔(比如 30 毫秒)并且需要在你想要的事件上启动——Component.onCompleted。将您的操作放入此计时器的onTriggered

代码如下:

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

    Timer 
        id: tm
        interval: 30
        onTriggered: dialog.open()
    

    StackView 
        id: stackView
        anchors.fill: parent
        // Implements back key navigation
        focus: true
        initialItem: Item 
            width: parent.width
            height: parent.heonTriggeredight
            Button  onClicked: dialog.open() 
            Component.onCompleted: tm.start()
        
    

    MyDialog  id: dialog 

【讨论】:

以上是关于显示对话框 onCompleted 无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

LibreOffice 对话框未按预期工作

jquery parseHTML 未按预期工作

以编程方式输入文本时,TextInput 无法按预期工作

可过滤在 Recyclerview 中无法按预期工作

Primefaces Accordion + Datatable过滤器/多项选择无法按预期工作

远程通知无法按预期工作