熟悉QML与C++混合编程的朋友都知道,QML想调用C++的属性时,需要在C++类中引入Q_PROPERTY
关键字,来按照一定格式书写类属性,如下所示:
Q_PROPERTY(QStringList multiPhoneStatusStr READ multiPhoneStatusStr WRITE setMultiPhoneStatusStr NOTIFY multiPhoneStatusStrChanged)
属性的设置和读取函数如下:
QStringList MultiCallInterface::multiPhoneStatusStr()
{
return m_phoneStatusStr;
}
void MultiCallInterface::setMultiPhoneStatusStr(const QStringList &statusStr)
{
m_phoneStatusStr = statusStr;
emit multiPhoneStatusStrChanged(statusStr);
}
本文要说的是信号multiPhoneStatusStrChanged(statusStr)
的使用,笔者认为这是Qt C++编程的核心之处。关于这个认识要从最近调试代码发现的问题说起:
我在调试一个多路通话的状态显示,需要每个子窗口分别独立显示各自状态,而这个值主要读取自m_phoneStatusStr
这个QStringList
类型的变量,而交互的C++类对象在实时更新这个值。我是这样写代码的:
m_phoneStatusStr.replace(idx, getPhoneStatusStr(PHONE_STATUS_CONVERSATION, idx) + m_callTimeCnt.at(idx));
前后代码可以忽略,只看这一行,直接修改m_phoneStatusStr
,它是个privite
类型,在C++中这么改当然没有问题,我也是图省事,写习惯了,但是界面反馈的结果是没有更新:
划红线的两个字符串"中国"和"美国"是我写的默认值,在程序运行中并没有再变化,而实际m_phoneStatusStr
是一直在更新的,这里就体现了Qt 中信号和槽的重要性了(具体原理定义网上资料很多,我就不赘述了),应该说信号和槽巧妙的连接了QML和C++的关系,它们就是桥梁,就是通信链路,写代码的时候要给自己提个醒,凡是涉及信号的变量,在后台C++修改变量的时候一定要把信号发射出去,否则QML不知道C++后台修改了什么?
所以在C++后台不能图省事直接修改m_phoneStatusStr
,而要发射对应的信号,也就是调用void MultiCallInterface::setMultiPhoneStatusStr(const QStringList &statusStr)
来修改参数,代码修改如下:
multiCallStr.replace(idx, getPhoneStatusStr(PHONE_STATUS_CONVERSATION, idx) + m_callTimeCnt.at(idx));
setMultiPhoneStatusStr(multiCallStr);
这样修改后,就得到了想要的结果,如图所示:
分别显示了各自的通话状态,达到预期。
一篇小小文加深下关于信号和槽
的理解,当然我这里没写槽,大佬就不用看了。