Qt多线程相关<一>

Refrence By:

http://www.cppblog.com/bitdewy/archive/2012/05/28/176553.html;

http://mobile.51cto.com/symbian-268690.htm;


更详细的深入讲解见参考:


最近遇到跨线程间信号槽的使用,终于找到一个较理想的解决方案,后续再深入学习其中的事件循环相关,这地方个人觉得才是信号槽或跨线程的精髓!


进入正题:


一般会遇到这样的问题,即在主线程中有些东西不方便处理,需要交给次级线程,这地方就需要用到信号槽机制,


connect(this,SIGNAL(),&thread,SLOT());


但是通常会遇到的问题是,sender和reciver的线程依附性一般都是相同的,该怎么处理呢?百思不得其解,没想到解决方案如此简单,就是将主线程不方便处理的


工作交给QObject的一个子类Child,然后将Child的线程依附性改变,类似如下:


Child::QObject

{

public slots:

dowork(){};

}

thread::QThread()

{
}

然后,Child.moveToThread(&thread);


各种玄机,请看代码


//mytest.h

#include <QtCore/QCoreApplication>   
#include <QtCore/QObject>   
#include <QtCore/QThread>   
#include <QtCore/QDebug>    
class Dummy : public QObject
{       
	Q_OBJECT   
public: 
	Dummy(QObject* parent=0):QObject(parent)
	{};   
public slots: 
	void emitsig()
	{        
		emit sig();       
	} 
signals: 
	void sig(); 
};    

class Object : public QObject 
{       
	Q_OBJECT   
public: 
	Object(){};
public slots:
	void slot() 
	{    
		qDebug()<<"from thread slot:" <<QThread::currentThreadId();       
	}   
}; 

//main.cpp


#include "mytest.h" 

int main(int argc, char *argv[]) 
{      
	QCoreApplication a(argc, argv);       
	qDebug()<<"main thread:"<<QThread::currentThreadId();      
	QThread thread;       
	Object obj;       
	Dummy dummy;       
	obj.moveToThread(&thread);      
	QObject::connect(&dummy, SIGNAL(sig()), &obj, SLOT(slot()));      
	thread.start();       
	dummy.emitsig();       
	return a.exec();
}

结果:


main thread: 0x1094 

from thread slot: 0x1498


OK,今天先到这里,其中还有许多不明白的地方,以后有机会再写!!


<think>嗯,用户问的是在Qt 5.14中如何通过信号和槽传递vector<double>变量。首先,我需要回忆Qt的信号槽机制对参数类型的要求。记得Qt的元对象系统(meta-object system)需要参数类型能够被识别,所以基本类型比如int、QString这些可以直接用,但像STL的vector<double>可能需要进行注册。 接下来,我需要确认在Qt 5.14中是否支持自动注册STL容器。Qt的版本更新可能会影响这点,比如某些版本可能开始支持更多的STL类型自动注册。但可能用户需要手动注册,特别是在旧版本中。不过Qt 5.14应该属于比较新的版本,可能已经支持部分容器的自动注册,但为了保险起见,可能需要手动注册。 然后,考虑如何注册vector<double>类型。通常的做法是使用qRegisterMetaType模板函数,在发送信号之前注册类型。比如qRegisterMetaType<std::vector<double>>("std::vector<double>");。需要注意的是,如果信号和槽是跨线程的,可能还需要使用Qt::QueuedConnection,这时候注册类型是必须的。 另外,还要检查信号和槽的声明是否正确。信号和槽的参数类型必须完全匹配,包括const和引用修饰符。例如,如果信号是void mySignal(const std::vector<double> &data),那么槽函数也应该接受同样的参数类型。 可能用户遇到的问题是没有注册类型导致连接失败,或者在跨线程使用时出现错误。这时候需要提示用户注册类型,并在连接信号槽时注意连接类型。 总结步骤应该是:1. 在适当的地方(比如main函数或类的构造函数)注册vector<double>类型;2. 在信号和槽声明中使用正确的参数类型;3. 确保连接方式正确,尤其是跨线程的情况。同时,提供示例代码会更有帮助,让用户清楚如何具体实现。 可能还需要提醒用户关于Qt版本的问题,不同版本可能有不同的支持情况,但Qt 5.14应该支持上述方法。另外,如果使用C++11或更高版本,模板的注册可能会更简单些,不需要额外的类型转换。 最后,检查是否有其他注意事项,比如包含必要的头文件,比如<vector>和<QMetaType>,以及确保元对象编译器(moc)能够处理这些类型,可能需要在使用信号和槽的类中包含Q_OBJECT宏。</think>在Qt 5.14中传递`std::vector<double>`通过信号槽需要注册元类型,具体步骤如下: --- ### 、核心原理 Qt的信号槽机制要求参数类型必须满足: 1. 能被Qt的元对象系统识别 2. 具有默认构造函数、拷贝构造函数和析构函数 3. 对于非Qt原生类型需要手动注册 --- ### 二、具体实现步骤 #### 1. 注册元类型 在包含信号/槽的类中(或main函数前)添加: ```cpp #include <QMetaType> #include <vector> // 在类构造函数或main函数中注册 qRegisterMetaType<std::vector<double>>("std::vector<double>"); ``` #### 2. 声明信号和槽 ```cpp // 发送方类头文件 signals: void dataReady(const std::vector<double>& data); // 接收方类头文件 public slots: void handleData(const std::vector<double>& data); ``` #### 3. 建立信号槽连接 ```cpp // 使用Qt5风格连接语法(推荐) QObject::connect(sender, &SenderClass::dataReady, receiver, &ReceiverClass::handleData); ``` #### 4. 发送信号示例 ```cpp std::vector<double> values {1.1, 2.2, 3.3}; emit dataReady(values); // 触发信号 ``` --- ### 三、重要注意事项 1. **跨线程通信**: ```cpp qRegisterMetaType<std::vector<double>>(); // 必须注册 connect(..., Qt::QueuedConnection); // 必须指定连接方式 ``` 2. **参数传递方式**: - 推荐使用`const &`传递避免拷贝 ```cpp void signalEmitted(const std::vector<double>& data); ``` 3. **Qt版本兼容性**: - Qt 5.9+ 支持更简洁的注册方式 - 旧版本可能需要: ```cpp Q_DECLARE_METATYPE(std::vector<double>) ``` --- ### 四、完整示例代码 ```cpp // 发送方类 class Sender : public QObject { Q_OBJECT public: void sendData() { std::vector<double> data {1.1, 2.2, 3.3}; emit dataSent(data); } signals: void dataSent(const std::vector<double>& data); }; // 接收方类 class Receiver : public QObject { Q_OBJECT public slots: void handleData(const std::vector<double>& data) { for(double val : data) { qDebug() << val; } } }; // main.cpp int main(int argc, char *argv[]) { QApplication a(argc, argv); qRegisterMetaType<std::vector<double>>(); Sender sender; Receiver receiver; QObject::connect(&sender, &Sender::dataSent, &receiver, &Receiver::handleData); sender.sendData(); return a.exec(); } ``` --- ### 五、常见问题解决 1. **编译报错`undefined reference to meta object`**: - 确保所有QObject派生类都包含Q_OBJECT宏 - 执行qmake重新生成moc文件 2. **运行时警告`Unknown parameter type`**: - 检查元类型注册是否正确 - 确保注册代码在信号发射前执行 3. **跨线程数据不同步**: - 使用深拷贝传递数据: ```cpp emit signal(std::vector<double>(data)); // 显式拷贝 ``` --- 通过以上步骤即可在Qt 5.14中安全地传递`std::vector<double>`类型数据。实际使用时建议封装为特定数据类型以提高代码可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值