有很多种方法,不过我这里只用QVariantMap,这样可以传单个、多个、结构体等等。
1、首先是C++传到QML,例如结构体转成map:
QVariantMap DataSource::readSystemConfig() { QVariantMap mapConfig; int ret = 0; // 要转换一下 if(ret == 0){ //DBG("struct 变成 map"); mapConfig.insert("adcLevel",m_sysConfig.adc_level); mapConfig.insert("adcDigit",m_sysConfig.adc_digit); mapConfig.insert("adcChs",m_sysConfig.adc_chs); mapConfig.insert("outLevelSet",m_sysConfig.out_level_set); mapConfig.insert("outIoVal",m_sysConfig.out_io_val); mapConfig.insert("canBd",m_sysConfig.can_bd);0 }0 return mapConfig; }
把C++对象注册到QML后,直接调用C++函数获取这个map:
onClicked: { var i=0; var cfg = cppObject.readSystemConfig(); // 更新到控件中 mcuConfigPage for(var key in cfg){ i++; mcuConfigPage.setText(key,cfg[key]) } if(i == 0) toast.show("获取失败") }
2、然后就是QML获取到数据回传到C++:
function getAllText(){ // 主要要有个空括号表示这个是map var map={}; map["adcLevel"] = adcLevel.getText(); map["adcDigit"] = adcDigit.getText(); map["adcChs"] = adcChs.getText(); map["outLevelSet"] = outLevelSet.getText(); map["outIoVal"] = outIoVal.getText(); map["canBd"] = canBd.getText(); return map; } // qml中这样调用: onSelectionChanged:{ var map; map = mcuConfigPage.getAllText(); if(dataSource.setSystemConfig(map) === false) toast.show("操作失败") }
C++方法:
bool DataSource::setSystemConfig(const QVariantMap mapConfig) { m_sysConfig.adc_level = mapConfig.value("adcLevel").toUInt(); m_sysConfig.adc_digit = mapConfig.value("adcDigit").toUInt(); m_sysConfig.adc_chs = mapConfig.value("adcChs").toUInt(); m_sysConfig.out_level_set = mapConfig.value("outLevelSet").toUInt(); m_sysConfig.out_io_val = mapConfig.value("outIoVal").toUInt(); m_sysConfig.can_bd = mapConfig.value("canBd").toUInt(); return m_abif->setSystemConfig(m_sysConfig) == ABI_NONE; }
=================其他方法探讨================
1、定义结构体时带Q_GADGET和Q_PROPERTY,然后就可以直接访问结构体成员(别名)了,具体看:
qt - Best way to access a cpp structure in QML - Stack Overflow
2、用QJSValue进行C++的引用传递
qt - How to pass data from QML to C++ as a mutable reference - Stack Overflow
Declaration: Q_INVOKABLE void select_company(int index,QJSValue out); Definition: void Companies::select_company(int index,QJSValue out) { out.setProperty("company_name","Acme, Inc."); out.setProperty("identity_id",29673); } QML: var retval={}; data_model.select_company(index,retval); console.log(retval.company_name); console.log(retval.identity_id);
3、QML中使用回调函数返回C++的数据:
qt - Passing a Javascript callback to a C++ Invoked method in Qml - Stack Overflow
4、官方:Data Type Conversion Between QML and C++ | Qt QML 5.15.14