Dynamic MessageDialog-文本从c++;但屏幕上没有更新

Dynamic MessageDialog-文本从c++;但屏幕上没有更新,dynamic,dialog,popup,qml,Dynamic,Dialog,Popup,Qml,我已经成功地动态更改了包含消息对话框的QML项中的几个属性。我可以读取新设置的属性,但它们不会在屏幕上更新-仍然是QML设置的可见文本。我甚至手动发送了一个textChanged()信号(见下文),但毫无效果 知道我错过了什么吗?我是这样做的: “ErrorDialog.qml”: 项目{ id:baseItem 属性字符串文本:“myText” 属性字符串标题:“myTitle” 信号接受信号() ContextChanged:{ errorDialogItem.text=baseItem.t

我已经成功地动态更改了包含
消息对话框的QML
项中的几个属性。我可以读取新设置的属性,但它们不会在屏幕上更新-仍然是QML设置的可见文本。我甚至手动发送了一个
textChanged()
信号(见下文),但毫无效果

知道我错过了什么吗?我是这样做的:

“ErrorDialog.qml”:

项目{
id:baseItem
属性字符串文本:“myText”
属性字符串标题:“myTitle”
信号接受信号()
ContextChanged:{
errorDialogItem.text=baseItem.text
}
消息对话框{
id:errorDialogItem
objectName:“errorDialogItem”
text:baseItem.text
标题:baseItem.title
不接受:{
接受信号()
}
Component.onCompleted:可见=真
}
现在,c++:

this->component=QSharedPointer(新的QQmlComponent(&this->engine));
QObject::connect(&引擎,信号(quit()),QCoreApplication::instance(),插槽(quit());
组件->加载URL(QUrl(QStringLiteral(“qrc:///main.qml")));
topLevel=QSharedPointer(组件->创建());
window=qobject_cast(topLevel.data());
surfaceFormat=window->requestedFormat();
窗口->设置格式(表面格式);
窗口->显示();
QQmlComponent对话框组件和引擎,QUrlqrc:///ErrorDialog.qml")));
QObject*myObject=dialogComponent.create();
QQuickItem*item=qobject\U cast(myObject);
QQmlEngine::setObjectOwnership(项,QQmlEngine::CppOwnership);
qDebug()方法(methodIndex);
qDebug()元对象()->方法(methodIndex);
qDebug()元对象()->方法(methodIndex);
qDebug()元对象()->方法(methodIndex);
qDebug()元对象()->方法(methodIndex);
qDebug()元对象()->方法(methodIndex);
qDebug()元对象()->方法(methodIndex);
qDebug()元对象()->方法(methodIndex);
QString textStr=“另一个文本”;
qDebug()元对象()->方法(methodIndex);

qDebug()感谢@BaCaRoZzo,在创建这个最小的示例时,我发现了问题所在。在打开
对话框之前,绝对必须进行属性更改,即处于关闭的状态。如果我想更改已打开的
MessageDialog
中的内容,我必须关闭它,更改pr属性,然后再次打开。仅更改属性,然后关闭并重新打开(如“重画”)是不够的。请参阅

在下面的
.h
文件中

这是我的工作代码,任何进一步的建议都非常感谢。注意:“Controller”类只是提供GUI的
qqqmlApplicationEngine
的一些类

C++类标题:
MessageDialog.h


我希望这可能有助于将来有人节省时间。

这里有一个替代SeDi答案的方法。它没有完全开发,但很简单,很容易根据自己的需要进行修改

实施示例

 MessageDialog::showCritcalError( myQmlEngine, "The sky is falling!" );
MessageDialog.h

#ifndef MESSAGEDIALOG_H
#define MESSAGEDIALOG_H

#include <QQmlEngine>

struct MessageDialog
{    
    static void showCritcalError( QQmlEngine *engine, const QString &message );
};

#endif // MESSAGEDIALOG_H

很难这样说。请提供一个最低限度的可测试示例。略读代码,有一些地方可以改进:对QML文件中的属性使用
alias
,例如
property alias text:errorDialogItem.text
,这样可以直接对内部属性进行操作,而无需添加额外变量。
#include "messagedialog.h"
#include <QQuickItem>
#include <QQmlApplicationEngine>
MessageDialog::MessageDialog(
        Controller *controller,
        QString title,
        QString text,
        QString informativeText,
        QString detailedText,
        StandardButtons buttons)
{
    Q_ASSERT(controller);
    this->initItem(controller);
    m_isOpen=false;
    m_result=MessageDialog::NoButton;
    this->setTitle(title);
    this->setText(text);
    this->setInformativeText(informativeText);
    this->setDetailedText(detailedText);
    this->setStandardButtons(buttons);
    this->connectQMLSignals();
}

MessageDialog::~MessageDialog()
{
    delete m_item;

}

void MessageDialog::setText(const QString &text)
{
    setItemProperty("text",text);
}

void MessageDialog::setInformativeText(const QString &text)
{
    setItemProperty("informativeText",text);
}

void MessageDialog::setDetailedText(const QString &text)
{
    setItemProperty("detailedText",text);
}

void MessageDialog::setTitle(const QString &title)
{
    setItemProperty("title",title);
}

void MessageDialog::setStandardButtons(StandardButtons buttons)
{
    setItemProperty("standardButtons",buttons);
    m_standardButtons=buttons;
}

void MessageDialog::addButton(MessageDialog::StandardButton button)
{
    m_standardButtons|=button;
    setItemProperty("standardButtons",m_standardButtons);
}


void MessageDialog::setIcon(MessageDialog::Icon icon)
{
    setItemProperty("icon",icon);
}

MessageDialog::StandardButton MessageDialog::clickedButton()
{
    int i=m_item->property("clickedButton").toInt();
    return static_cast<MessageDialog::StandardButton>(i);
}

void MessageDialog::setModality(Qt::WindowModality modality)
{
    setItemProperty("modality",modality);
}

int MessageDialog::result()
{
    return this->clickedButton();
}

MessageDialog::StandardButton MessageDialog::exec()
{
    QEventLoop loop;

    connect(m_item, SIGNAL(accepted()),& loop,
           SLOT(quit()),Qt::UniqueConnection);
    connect(m_item, SIGNAL(apply()),& loop,
           SLOT(quit()),Qt::UniqueConnection);
    connect(m_item, SIGNAL(discard()),& loop,
           SLOT(quit()),Qt::UniqueConnection);
    connect(m_item, SIGNAL(help()),& loop,
           SLOT(quit()),Qt::UniqueConnection);
    connect(m_item, SIGNAL(no()),& loop,
           SLOT(quit()),Qt::UniqueConnection);
    connect(m_item, SIGNAL(rejected()),& loop,
           SLOT(quit()),Qt::UniqueConnection);
    connect(m_item, SIGNAL(reset()),& loop,
           SLOT(quit()),Qt::UniqueConnection);
    connect(m_item, SIGNAL(yes()),& loop,
           SLOT(quit()),Qt::UniqueConnection);
    invokeMethod("open()");
    setModality(Qt::ApplicationModal);
    loop.exec();
    return this->clickedButton();
}

void MessageDialog::about(
        Controller *controller,
        const QString &title,
        const QString &text,
        const QString &informativeText,
        const QString &detailedText)

{
    MessageDialog dialog(controller);
    dialog.setStrings(title,text,informativeText,detailedText);
    dialog.setIcon(MessageDialog::Information);
    dialog.setStandardButtons(Ok);
    dialog.exec();
}

MessageDialog::StandardButton MessageDialog::warning(
        Controller *controller,
        const QString &title,
        const QString &text,
        const QString &informativeText,
        const QString &detailedText,
        MessageDialog::StandardButton button0,
        MessageDialog::StandardButton button1,
        MessageDialog::StandardButton button2,
        MessageDialog::StandardButton button3)
{
    MessageDialog dialog(controller);
    dialog.setStrings(title,text,informativeText,detailedText);
    dialog.setIcon(MessageDialog::Warning);
    dialog.setStandardButtons(
           StandardButtons(button0|button1|button2|button3));
    dialog.exec();
    return dialog.clickedButton();
}

MessageDialog::StandardButton MessageDialog::information(
        Controller *controller,
        const QString &title,
        const QString &text,
        const QString &informativeText,
        const QString &detailedText,
        MessageDialog::StandardButton button0,
        MessageDialog::StandardButton button1,
        MessageDialog::StandardButton button2,
        MessageDialog::StandardButton button3)
{
    MessageDialog dialog(controller);
    dialog.setStrings(title,text,informativeText,detailedText);
    dialog.setIcon(MessageDialog::Information);
    dialog.setStandardButtons(
           StandardButtons(button0|button1|button2|button3));
    dialog.exec();
    return dialog.clickedButton();
}

bool MessageDialog::open()
{
    Q_ASSERT(m_item);
    if (m_isOpen) return false;
    m_isOpen=invokeMethod("open()");
    return m_isOpen;
}

bool MessageDialog::close()
{
    Q_ASSERT(m_item);
    if (!m_isOpen) return false;
    m_isOpen=!invokeMethod("close()");
    return !m_isOpen;
}

bool MessageDialog::invokeMethod(QString methodSignature)
{
    Q_ASSERT(m_item);
    int methodIndex;
    methodIndex=m_item->metaObject()->indexOfMethod(
                                       methodSignature.toLocal8Bit());
    QMetaMethod method = m_item->metaObject()->method(methodIndex);
    return method.invoke(m_item,Qt::DirectConnection);
}

bool MessageDialog::setStrings(
        const QString &title,
        const QString &text,
        const QString informativeText,
        const QString detailedText)
{
    bool success=true;
    success &= this->setItemProperty("title",title);
    success &= this->setItemProperty("text",text);
    success &= this->setItemProperty("informativeText",informativeText);
    success &= this->setItemProperty("detailedText",detailedText);
    return success;
}

void MessageDialog::initItem(Controller *controller)
{
    m_engine=controller->engine();
    Q_ASSERT(m_engine);
    QQmlComponent* myComponent=new QQmlComponent(
           m_engine, QUrl(QStringLiteral("qrc:/MessageDialog.qml")));
    Q_ASSERT(myComponent);
        if (!myComponent->isReady()) {
        qWarning("%s", qPrintable(myComponent->errorString()));
    }
    QObject *myObject = myComponent->create();
    Q_ASSERT(myObject);
    m_item = qobject_cast<QQuickItem*>(myObject);
    Q_ASSERT(m_item);
    QQmlApplicationEngine::setObjectOwnership(
               m_item,QQmlApplicationEngine::CppOwnership);

}

void MessageDialog::connectQMLSignals()
{
    connect(m_item, SIGNAL(accepted()),this, SIGNAL(accepted()));
    connect(m_item, SIGNAL(apply()),this, SIGNAL(apply()));
    connect(m_item, SIGNAL(discard()),this, SIGNAL(discard()));
    connect(m_item, SIGNAL(help()),this, SIGNAL(help()));
    connect(m_item, SIGNAL(no()),this, SIGNAL(no()));
    connect(m_item, SIGNAL(rejected()),this, SIGNAL(rejected()));
    connect(m_item, SIGNAL(reset()),this, SIGNAL(reset()));
    connect(m_item, SIGNAL(yes()),this, SIGNAL(yes()));
}
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Dialogs 1.2
Item{
    id: baseItem
    property alias text: errorDialogItem.text
    property alias detailedText: errorDialogItem.detailedText
    property alias informativeText: errorDialogItem.informativeText
    property alias title: errorDialogItem.title
    property alias modality: errorDialogItem.modality
    property alias standardButtons: errorDialogItem.standardButtons
    property alias icon: errorDialogItem.icon
    property alias clickedButton: errorDialogItem.clickedButton
    property alias standardIconSource: 
                       errorDialogItem.standardIconSource

    signal accepted()
    signal apply()
    signal discard()
    signal help()
    signal no()
    signal rejected()
    signal reset()
    signal yes()


    function open() {
        return errorDialogItem.open()
    }
    function close() {
        return errorDialogItem.close()
    }
    MessageDialog {
        id: errorDialogItem
        objectName: "errorDialogItem"

        onAccepted: baseItem.accepted()
        onApply: baseItem.apply()
        onDiscard: baseItem.discard()
        onHelp: baseItem.help()
        onNo: baseItem.no()
        onRejected: baseItem.rejected()
        onReset: baseItem.reset()
        onYes: baseItem.yes()

    }

}
 MessageDialog::showCritcalError( myQmlEngine, "The sky is falling!" );
#ifndef MESSAGEDIALOG_H
#define MESSAGEDIALOG_H

#include <QQmlEngine>

struct MessageDialog
{    
    static void showCritcalError( QQmlEngine *engine, const QString &message );
};

#endif // MESSAGEDIALOG_H
#include "MessageDialog.h"

#include <QQmlComponent>
#include <QQuickItem>

// ---------------------------------

static const QString QML_RESOURCE_PREFIX( "qrc:/" );
static const QString DIALOG_QML( "MessgeDialog.qml" );

static const char *TITLE_PROP   = "dialogTitle";
static const char *ICON_PROP    = "dialogIcon";
static const char *TEXT_PROP    = "dialogText";
static const char *VISIBLE_PROP = "dialogVisible";

static const QString INFO_DEFAULT_TITLE(     "Information" );
static const QString WARNING_DEFAULT_TITLE(  "Warning" );
static const QString CRITICAL_DEFAULT_TITLE( "Error" );
static const QString QUESTION_DEFAULT_TITLE( "Question" );

static const int NO_ICON = 0,
               INFO_ICON = 1,
                 WARNING = 2,
           CRITICAL_ICON = 3,
           QUESTION_ICON = 4;

void showMessageDialog( QQmlEngine *engine,
    const QString &title, const int icon, const QString &text  )
{
    QQmlComponent component( engine, QUrl( QML_RESOURCE_PREFIX + DIALOG_QML ) );
    QQuickItem *item = qobject_cast<QQuickItem*>( component.create() );
    item->setProperty( TITLE_PROP,   title );
    item->setProperty( ICON_PROP,    icon );
    item->setProperty( TEXT_PROP,    text );
    item->setProperty( VISIBLE_PROP, true ); // must do last after setting other properties
}

// ---------------------------------

void MessageDialog::showCritcalError( QQmlEngine *engine, const QString &message )
{ showMessageDialog( engine, CRITICAL_DEFAULT_TITLE, CRITICAL_ICON, message ); }
import QtQuick 2.2
import QtQuick.Dialogs 1.1

Item {
    property string dialogTitle: ""
    property int     dialogIcon: 0
    property string  dialogText: ""
    property bool dialogVisible: false
    MessageDialog {
        id: messageDialog
        title   : dialogTitle
        icon    : dialogIcon
        text    : dialogText
        visible : dialogVisible
        modality: Qt.ApplicationModal
    }
}