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