如何在重用 QML 组件时读写属性更改

Posted

技术标签:

【中文标题】如何在重用 QML 组件时读写属性更改【英文标题】:How to read-write properties changes at reusing QML components 【发布时间】:2014-08-19 10:34:50 【问题描述】:

我有 QMLDoubleEdit 这样的组件

import QtQuick 1.1
Item
property double dVal: 0;
Rectangle 

    TextInput 
        id: textDVal
        focus:true
        validator:DoubleValidator
            bottom:0;
            top:200;
            decimals: 3
                   
        text: dVal           
    

例如当它用于实现 UI 时

Item
property double dWesMax:    0;
property double dWesMin:    0;


Rectangle        
    QMLDoubleEdit 
        id: edtMaxWes
        x: 40
        y: 50
        dVal: dWesMax
    

    QMLDoubleEdit 
        id: edtMinWes
        x: 260
        y: 50
        dVal: dWesMin
    
 
 

我可以从我的 *.cpp 代码中为其设置初始值,但更改后我无法读取它们:

//没关系

QDeclarativeContext *context=m_qmlFrmParam->rootContext();
    context->setContextProperty("dWesMax",m_wntModule->getWesMax());

// 那不是

double dVal=0;
dVal=(m_dlgRoot->property("dWesMax")).toDouble();

在这里更好地解释: 1)创建用户界面

void frmWesParam::prepareElements()
m_qmlFrmParam=new QDeclarativeView();
m_qmlFrmParam->setSource(QUrl("qrc:/view/wesparams/QMLBgPanel.qml"));
m_qmlFrmParam->setResizeMode(QDeclarativeView::SizeRootObjectToView);
m_dlgRoot=m_qmlFrmParam->rootObject();
QDeclarativeContext *context=m_qmlFrmParam->rootContext();
context->setContextProperty("viewerWidget",this);


void frmWesParam::setWesMax(double dVal)
m_dlgRoot->setProperty("dWesMax",QString::number(dVal));

2) 显示它(只有一行元素 QMLDoubleEdit,和两个按钮 - “Ok”、“Cancel” onPress,发出接受或取消)

frmWesParam *vw=new frmWesParam();
vw->setWesMax(14.3);
vw->show();

3) 当小部件出现时,它包含我的值 - 14.3。 在这里用户可以改变它,并按下按钮; 4) 在信号接受时我得到了

void frmWesParam::catchAccept()
if(m_wntModule!=0)
double dVal=0;
dVal=(m_dlgRoot->property("dWesMax")).toDouble();
qDebug()<<dVal;
     

在这里,我得到的只是我所坐的 setWesMax(...) 。

【问题讨论】:

m_dlgRoot 是什么?您在 C++ 中设置的上下文属性与 QML 代码中的上下文属性是否不同?使用setContextProperty 设置的属性可以使用同一上下文的contextProperty 成员函数读取。 是的,是这样,但我在 QMLDoubleEdit 中更改了值,但无法读取; m_qmlFrmParam=new QDeclarativeView(); .... m_dlgRoot=m_qmlFrmParam->rootObject(); 看不懂是什么意思?你得到的是初始值还是无效的 QVariant? 我有我通过 setContext() 设置的值 【参考方案1】:

正如我在 cmets 中所说,更改 TextInput 中的值不会更改 dWesMax 属性。您应该在 C++ 中阅读 TextInputtext 属性,或者在更改 TextInput 时让 QML 更新 dWesMax。以下是您可以如何做到的示例:

QMLDoubleEdit

import QtQuick 1.1
Item
property double dVal: 0;
property var textChangedCb: null;
Rectangle 

    TextInput 
        id: textDVal
        focus:true
        validator:DoubleValidator
            bottom:0;
            top:200;
            decimals: 3
                   
        text: dVal
        onTextChanged: dVal = text; if (textChangedCb) textChangedCb();
    

界面代码

Item
property double dWesMax:    0;
property double dWesMin:    0;


Rectangle        
    QMLDoubleEdit 
        id: edtMaxWes
        x: 40
        y: 50
        dVal: dWesMax
        textChangedCb: dWesMax = dVal;
    

    QMLDoubleEdit 
        id: edtMinWes
        x: 260
        y: 50
        dVal: dWesMin
        textChangedCb: dWesMin = dVal;
    
 

这不是最简洁的方法,但它可以在不更改 C++ 代码和 QML 结构的情况下工作。

【讨论】:

感谢回答,我会试试的 我有了概念性的想法,谢谢。在一些正确的我会发布一段工作代码【参考方案2】:

在 W.B. 的帮助下,我得到了另一个解决方案

用户界面:

Item
 property alias dWesMax:    edtMaxWes.dVal;
 property alias dWesMin:    edtMinWes.dVal;


 Rectangle        
 QMLDoubleEdit 
     id: edtMaxWes
     x: 40
     y: 50
 

 QMLDoubleEdit 
    id: edtMinWes
    x: 260
    y: 50
 


QMLDoubleEdit:

Item
 property double dVal: 0;

 Rectangle 
    TextInput 
        id: textDVal
        validator:DoubleValidator
            bottom:0;
            top:200;
            decimals: 3
        
        onTextChanged: 
            if(text.length>0)
              dVal=parseFloat(text);
            
        

    


【讨论】:

以上是关于如何在重用 QML 组件时读写属性更改的主要内容,如果未能解决你的问题,请参考以下文章

QML 焦点如何传播?

如何使用QML StackView的status属性?

如何在qt qml中更改地图上代表组件的颜色

如何在属性更改 QML 上实现行为动画

QML 可重用组件

如何在 QML 视图之间动态更改