网站logo设计思路,网站建设的中期检查表,软件商店oppo下载,坚持网站机制建设Qt的官方文档虽然并没有明确说明#xff0c;不能在子线程中操作UI#xff0c;但是#xff0c;因为Qt是事件循环机制#xff0c;所有的UI事件都是在主线程中处理的#xff0c;如果在子线程中直接操作UI#xff0c;就会存在线程安全问题#xff0c;严重时候会使程序挂掉。… Qt的官方文档虽然并没有明确说明不能在子线程中操作UI但是因为Qt是事件循环机制所有的UI事件都是在主线程中处理的如果在子线程中直接操作UI就会存在线程安全问题严重时候会使程序挂掉。 但是有些场景确实需要在子线程中操作UI怎么办以下是几种常用的解决方案 1. 使用信号槽机制 这种方式是当子线程中需要对ui对象进行操作时发出一个信号在与之连接的槽中处理ui操作。信号和槽的连接方式必须是BlockingQueuedConnection 或QueuedConnection 的连接方式连接。 2. 使用自定义event 在子线程中通过QCoreApplication::postEvent 发出自定义的event在对应的ui对象中重写customevent中处理自定义的event 。 3. 使用QMetaObject::invokeMethod()函数 该函数是一个静态函数可以直接使用用于调用对象的元对象方法 。该函数功能很强大这里是用到了其可以在不同线程之间调用对象方法的特性。 如果是新代码可以在程序设计之初就处理好子线程与UI操作之间的协调处理这种情况比较好办可以使用方法1和方法2进行处理。但是如果是维护历史代码重新做设计肯定是不现实的所以就需要使用方法3进行处理在子线程中操作UI的代码段修改为QMetaObject::invokeMethod函数调用可以做到最小程度的代码修改下面给出具体例子
// 在子线程中调用
int rowCount 0
REPORT_DE_INFO reportInfo
bool b QMetaObject::invokeMethod(this, initTablewidget, Qt::BlockingQueuedConnection, Q_RETURN_ARG(int, rowCount), Q_ARG(REPORT_DE_INFO, reportInfo));参数说明 参数1调用对象指针 参数2调用的方法名 参数3连接方式与信号槽连接函数connect的最后一个参数相同。对于这里是维护历史代码的场景建议使用BlockingQueuedConnection原来代码的执行逻辑一定是先执行完函数后才继续往下走如果这里不给阻塞住函数还没执行完子线程就会继续往下走很显然这与原来的代码逻辑并不相同很可能会出现错误 参数4Q_RETURN_ARG宏用来接收函数的返回值宏的第1个参数是返回值类型第2个参数是接收返回值的变量名 参数5Q_ARG宏用来向函数传递参数宏的第1个参数是函数参数的类型第2个参数是传递参数的变量名如果函数有多个参数可以继续往下使用Q_ARG宏来传递 返回值bool类型执行成功或者失败 注意执行的函数一定要是槽函数否者回执行失败