Results 1 to 5 of 5

Thread: ContextProperty of QQmlPropertyMap object is not writable at qml

  1. #1
    Join Date
    Jan 2025
    Posts
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt5

    Post ContextProperty of QQmlPropertyMap object is not writable at qml

    Hello
    I have a conventional QQmlPropertyMap of contextproeprty working pretty well at qml ( is being read pretty well )
    but at the qml side I am not able to write any new value to it . what could be the reason of making QQmlPropertyMap object is not writable at qml side ?

    here is the C++ code side:

    Qt Code:
    1. QQmlPropertyMap* gDataProp;
    2. int main(int argc, char *argv[])
    3. {
    4. set_qt_environment();
    5. QGuiApplication app(argc, argv);
    6. ControlObjTreeModel uiObjectTreeMod;
    7. gDataProp =new QQmlPropertyMap();
    8. gDataProp->insert(mapNumOfSchObj,0);
    9. QJsonObject paramObj ={{shcObjName,"K0"} };
    10. QJsonObject paramIns[3];
    11. QJsonObject paramOut[2];
    12.  
    13. paramIns[0]={{ portName,"IN0"} , { portID,1}};
    14. paramIns[1]={{ portName,"IN1"} , { portID,2}};
    15. paramIns[2]={{ portName,"IN2"} , { portID,3}};
    16.  
    17. paramOut[0]={{ portName,"Out0"} , { portID,1}};
    18. paramOut[1]={{ portName,"Out1"} , { portID,2}};
    19.  
    20. GroupObject gIns [3];
    21. GroupObject gOuts [2];
    22.  
    23. qDebug() <<paramObj;
    24.  
    25. knx1 =new InterfaceObject(gDataProp,&paramObj ,paramIns, paramOut, gIns,gOuts ,3,2);
    26. paramObj[shcObjName]="Sw";
    27. sw1 =new InterfaceObject(gDataProp,&paramObj ,paramIns, paramOut, gIns,gOuts ,3,2);
    28.  
    29. QQmlApplicationEngine engine;
    30. const QUrl url(u"qrc:/qt/qml/Main/main.qml"_qs);
    31.  
    32. QObject::connect(
    33. &engine,
    34. &QQmlApplicationEngine::objectCreated,
    35. &app,
    36. [url](QObject *obj, const QUrl &objUrl) {
    37. if (!obj && url == objUrl)
    38. QCoreApplication::exit(-1);
    39. },
    40. Qt::QueuedConnection);
    41.  
    42. // BOLDFACE by OP for emphasis (Mod.)
    43. engine.rootContext()->setContextProperty("gDatPr", gDataProp );
    44. //
    45.  
    46. engine.addImportPath(QCoreApplication::applicationDirPath() + "/qml");
    47. engine.addImportPath(":/");
    48. engine.load(url);
    49.  
    50. if (engine.rootObjects().isEmpty()) {
    51. return -1;
    52. }
    53.  
    54. return app.exec();
    55. }
    56.  
    57. InterfaceObject:: InterfaceObject(QQmlPropertyMap * dmap ,QJsonObject* objParams
    58. , QJsonObject* insParam , QJsonObject* outsParam,
    59. GroupObject *inGo ,GroupObject *outGo, uint16_t numIns , uint16_t numOuts)
    60. :QObject (dmap)
    61. {
    62. int numOfSchObj ;
    63. schDataMap= dmap;
    64. interfaceData= new QJsonObject (*objParams);
    65. numOfIns=numIns;
    66. numOfOuts=numOuts;
    67. qDebug()<<*interfaceData;
    68.  
    69. numOfSchObj =schDataMap->value(mapNumOfSchObj).toInt();
    70. interfaceData->insert(shcObjID,numOfSchObj+1);
    71.  
    72. ins = new InterfacePort*[numIns];
    73. outs = new InterfacePort*[numOuts];
    74.  
    75. for (uint16_t i=0;i<numIns;i++)
    76. {
    77. ins [i]=new InterfacePort(insParam[i], inGo[i]);
    78. jsonArrayIn.push_back(ins [i]->getPortObj());
    79. }
    80.  
    81. interfaceData->insert(shcObjIns,jsonArrayIn);
    82. interfaceData->insert(shcObjNumOfIns,numOfIns);
    83. qDebug()<<*interfaceData;
    84.  
    85. for (uint16_t i=0;i<numOuts;i++)
    86. {
    87. outsParam[i].insert(pConnectionTarObjID,-2);
    88. outsParam[i].insert(pConnectionTarPortID,-4);
    89. outs [i]=new InterfacePort(outsParam[i], outGo[i]);
    90. jsonArrayIn2.push_back(outs[i]->getPortObj());
    91. }
    92.  
    93. interfaceData->insert(shcObjOuts,jsonArrayIn2);
    94. interfaceData->insert(shcObjNumOfOuts,numOfOuts);
    95.  
    96. objKey=new QString (mapSchObjHeader + QString::number(numOfSchObj));
    97. schDataMap->insert(*objKey , *interfaceData);
    98.  
    99. // BOLDFACE by OP for emphasis (Mod.)
    100. schDataMap->insert( mapNumOfSchObj ,numOfSchObj+1);
    101.  
    102.  
    103. schDataMap->connect(
    104. schDataMap,
    105. &QQmlPropertyMap::valueChanged,
    106. this,
    107. &InterfaceObject::updateFromGuiSlot);
    108. // end boldface
    109.  
    110. }
    To copy to clipboard, switch view to plain text mode 
    and in qml Side:
    gDatPr["SO0"] [api.shcObjName]="newName"
    console.log( "test Name ",gDatPr["SO0"] [api.shcObjName])



    console.log is still showing the old name "K0"


    *** Moderator's note: inserted CODE tags for readability. I apologize that embedded boldface font is not supported in CODE sections. Hopefully my added comments will help.
    Last edited by d_stranz; 26th January 2025 at 17:52. Reason: missing [code] tags

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,287
    Thanks
    310
    Thanked 868 Times in 855 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: ContextProperty of QQmlPropertyMap object is not writable at qml

    Everything that you are doing in this main() code is happening before the Qt event loop starts running (app.exec()). If the QML <-> C++ interaction depends on Qt events, signals, and slots, then nothing that happens before the event loop is running will have any effect.

    So you need a QMainWindow or some other GUI where this code runs, after the QMainWindow constructor has exited and the GUI is active (eg. after the showEvent()).
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Jan 2025
    Posts
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt5

    Default Re: ContextProperty of QQmlPropertyMap object is not writable at qml

    Quote Originally Posted by d_stranz View Post
    Everything that you are doing in this main() code is happening before the Qt event loop starts running (app.exec()). If the QML <-> C++ interaction depends on Qt events, signals, and slots, then nothing that happens before the event loop is running will have any effect.

    So you need a QMainWindow or some other GUI where this code runs, after the QMainWindow constructor has exited and the GUI is active (eg. after the showEvent()).
    Many thanks for your support Mr. d_stranz ... I missed the Threading model at this small test..
    I got the Thread model running OK but I am still not able to write any new value the QQmlPropertyMap object at qml side !!
    here is the new C++ code:



    Qt Code:
    1. MainWindowCC * mWindow;
    2. QTranslator trans1;
    3. int main(int argc, char *argv[])
    4. {
    5. set_qt_environment();
    6. QGuiApplication app(argc, argv);
    7. mWindow = new MainWindowCC (& app ,&trans1);
    8. mWindow->start();
    9.  
    10.  
    11. return app.exec();
    12. }
    13.  
    14. MainWindowCC::MainWindowCC(QGuiApplication *app, QTranslator *mtrans)
    15.  
    16. : QThread()
    17. {
    18. gDataProp =new QQmlPropertyMap();
    19. gDataProp->insert(mapNumOfSchObj,0);
    20. QJsonObject paramObj ={{shcObjName,"K0"} };
    21. QJsonObject paramIns[3];
    22. QJsonObject paramOut[2];
    23.  
    24. paramIns[0]={{ portName,"IN0"} , { portID,1}};
    25. paramIns[1]={{ portName,"IN1"} , { portID,2}};
    26. paramIns[2]={{ portName,"IN2"} , { portID,3}};
    27.  
    28. paramOut[0]={{ portName,"Out0"} , { portID,1}};
    29. paramOut[1]={{ portName,"Out1"} , { portID,2}};
    30.  
    31. GroupObject gIns [3];
    32. GroupObject gOuts [2];
    33.  
    34. qDebug() <<paramObj;
    35.  
    36. knx1 =new InterfaceObject(app,gDataProp,&paramObj ,paramIns, paramOut, gIns,gOuts ,3,2);
    37. knx1->start();
    38. paramObj[shcObjName]="Sw";
    39. sw1 =new InterfaceObject(app,gDataProp,&paramObj ,paramIns, paramOut, gIns,gOuts ,3,2);
    40. sw1->start();
    41.  
    42. const QUrl url(u"qrc:/qt/qml/Main/main.qml"_qs);
    43.  
    44. QObject::connect(
    45. &engine,
    46. &QQmlApplicationEngine::objectCreated,
    47. app,
    48. [url](QObject *obj, const QUrl &objUrl) {
    49. if (!obj && url == objUrl)
    50. QCoreApplication::exit(-1);
    51. },
    52. Qt::QueuedConnection);
    53.  
    54. engine.rootContext()->setContextProperty("gDatPr", gDataProp );
    55. engine.rootContext()->setContextProperty("uiObjectTreeModel", &uiObjectTreeMod );
    56.  
    57. engine.addImportPath(QCoreApplication::applicationDirPath() + "/qml");
    58. engine.addImportPath(":/");
    59. engine.load(url);
    60.  
    61. }
    62.  
    63.  
    64. InterfaceObject:: InterfaceObject(QGuiApplication *app,QQmlPropertyMap * dmap ,QJsonObject* objParams
    65. , QJsonObject* insParam , QJsonObject* outsParam,
    66. GroupObject *inGo ,GroupObject *outGo, uint16_t numIns , uint16_t numOuts)
    67. :QThread ()
    68. {
    69. int numOfSchObj ;
    70. schDataMap= dmap;
    71. interfaceData= new QJsonObject (*objParams);
    72. numOfIns=numIns;
    73. numOfOuts=numOuts;
    74. qDebug()<<*interfaceData;
    75.  
    76. numOfSchObj =schDataMap->value(mapNumOfSchObj).toInt();
    77. interfaceData->insert(shcObjID,numOfSchObj+1);
    78.  
    79. ins = new InterfacePort*[numIns];
    80. outs = new InterfacePort*[numOuts];
    81.  
    82. for (uint16_t i=0;i<numIns;i++)
    83. {
    84. ins [i]=new InterfacePort(insParam[i], inGo[i]);
    85. jsonArrayIn.push_back(ins [i]->getPortObj());
    86. }
    87.  
    88. interfaceData->insert(shcObjIns,jsonArrayIn);
    89. interfaceData->insert(shcObjNumOfIns,numOfIns);
    90. qDebug()<<*interfaceData;
    91.  
    92. for (uint16_t i=0;i<numOuts;i++)
    93. {
    94. outsParam[i].insert(pConnectionTarObjID,-2);
    95. outsParam[i].insert(pConnectionTarPortID,-4);
    96. outs [i]=new InterfacePort(outsParam[i], outGo[i]);
    97. jsonArrayIn2.push_back(outs[i]->getPortObj());
    98. }
    99.  
    100. interfaceData->insert(shcObjOuts,jsonArrayIn2);
    101. interfaceData->insert(shcObjNumOfOuts,numOfOuts);
    102.  
    103. objKey=new QString (mapSchObjHeader + QString::number(numOfSchObj));
    104. schDataMap->insert(*objKey , *interfaceData);
    105. schDataMap->insert( mapNumOfSchObj ,numOfSchObj+1);
    106.  
    107.  
    108. QObject::connect(
    109. schDataMap,
    110. &QQmlPropertyMap::valueChanged,
    111. this,
    112. &InterfaceObject::updateFromGuiSlot);
    113.  
    114. }
    115.  
    116. void InterfaceObject::updateFromGuiSlot(const QString &key, const QVariant &value)
    117. {
    118. qDebug ()<<"Obj:"<<*objKey<<" before conditionhas been updated .. I am in its slot now";
    119. if(key==*objKey)
    120. {
    121. qDebug ()<<"Obj:"<<*objKey<<" has been updated .. I am in its slot now";
    122. }
    123. }
    124. void InterfaceObject::run()
    125. {
    126. while(loopActive==true)
    127. {
    128. //
    129.  
    130. }
    131. }
    To copy to clipboard, switch view to plain text mode 

    and in the qml side:
    Qt Code:
    1. gDatPr["SO0"] [api.shcObjName]="new Name"
    2. console.log( "test Name: ",gDatPr["SO0"] [api.shcObjName])
    To copy to clipboard, switch view to plain text mode 
    console is still showing the old name ("test Name: K0")

    wha t could be the reason that QQmlPropertyMap object is not connected with its valueChanged Event , and not writable at qml side_
    Last edited by AmerQ; 27th January 2025 at 14:35.

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,287
    Thanks
    310
    Thanked 868 Times in 855 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: ContextProperty of QQmlPropertyMap object is not writable at qml

    It still looks to me as though you are executing all of this code before the event loop is running. Things that happen in your MainWindowCC and InterfaceObject constructors are taking place before app.exec() (which starts the event loop). Your connect() statements set up signal-slot connections, but any signals emitted are ignored if the event loop is not running.

    Anyway, if that isn't the problem, I can't be of much more help. I don't use qml and do not have any experience with it. What I am saying is from my own experience with C++ and unsuccessfully trying to use signals and slots before an event loop is running.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Jan 2025
    Posts
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt5

    Default Re: ContextProperty of QQmlPropertyMap object is not writable at qml

    Quote Originally Posted by d_stranz View Post
    It still looks to me as though you are executing all of this code before the event loop is running. Things that happen in your MainWindowCC and InterfaceObject constructors are taking place before app.exec() (which starts the event loop). Your connect() statements set up signal-slot connections, but any signals emitted are ignored if the event loop is not running.

    Anyway, if that isn't the problem, I can't be of much more help. I don't use qml and do not have any experience with it. What I am saying is from my own experience with C++ and unsuccessfully trying to use signals and slots before an event loop is running.

    Hello Mr.d_stranz
    Many thanks for your support.
    it seems that qml doesn't accept writing to multilevel JSON object like the next anymore:
    Qt Code:
    1. gDatPr["SO0"] [api.shcObjName]="newName"
    To copy to clipboard, switch view to plain text mode 

    but it do accept :
    Qt Code:
    1. var tempVar=gDatPr["SO0"]
    2. tempVar[api.shcObjName] ="newName"
    3. gDatPr["SO0"] =tempVar
    To copy to clipboard, switch view to plain text mode 

    i tworked like this , and the connected signal/slots are working as well

  6. The following user says thank you to AmerQ for this useful post:

    d_stranz (28th January 2025)

Similar Threads

  1. Replies: 1
    Last Post: 13th December 2018, 18:24
  2. TypeError: Object [object Object] has no method 'sendData'
    By TheIndependentAquarius in forum Qt Quick
    Replies: 2
    Last Post: 30th November 2013, 06:54
  3. QQmlPropertyMap, model
    By sBoff in forum Qt Quick
    Replies: 7
    Last Post: 27th August 2013, 11:33
  4. Replies: 3
    Last Post: 11th July 2012, 13:40
  5. Replies: 1
    Last Post: 8th November 2011, 23:27

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.