// worker类,继承,OBject,头文件
class worker : public QObject
{
Q_OBJECT
public:
explicit worker(QObject *parent = nullptr);
void test();
public slots:
void dowork1();
void dowork2();
void dowork3();
signals:
void singalwork();
};
//worker实现
worker::worker(QObject *parent) : QObject(parent)
{
qDebug() << " Workd Create , 当前ThreadID:"<<QThread::currentThreadId();
}
void worker::test()
{
qDebug() << " Workd Test FUNC 成员函数ThreadID:"<<QThread::currentThreadId();
}
void worker::dowork1()
{
qDebug() << "doWork1 ThreadID:"<<QThread::currentThreadId();
}
void worker::dowork2()
{
qDebug() << "doWork2 ThreadID:"<<QThread::currentThreadId();
}
void worker::dowork3()
{
qDebug() << "doWork3 ThreadID:"<<QThread::currentThreadId();
}
int main()
{
// OBJECT 线程
mywork = new worker();
thr1 = new QThread();
mywork->moveToThread(thr1);
QObject::connect(thr1, &QThread::started,mywork,[=](){ mywork->dowork2(); }); //dowork2在子线程执行
/*
解释:
connect(sender, signal, lambda);
等于
connect(sender, signal, sender, lambda);
// 这样才会跑在主线程!
connect(thr1, &QThread::started, this, [=](){
mywork->dowork2(); // 这里会在主线程执行!!!
});
// 假设 started 信号带参数:started(int value) 线程传参
QObject::connect(thr1, &QThread::started, mywork, [=](int value){
// 这里可以直接用 value!
qDebug() << "收到参数:" << value;
// 原来的逻辑不变
mywork->dowork2();
});
//变量捕获,[=] [&] 用法:
1、只读、简单变量 → 用 [=](值捕获)
安全,无野指针 / 悬空引用风险,
int a = 99;
QString test = "this is a test string!";
// [=] 是值捕获:把 a 和 test 复制一份存到 Lambda 里
connect(thr1, &QThread::started, this, [=](){
qDebug() << "a:" << a << "test:" << test;
mywork->dowork2();
// 这里编译器自动生成了一个 【副本 int a = 99;】
fun(&a); //这里的副本a的生命周期,和Lambda同生共死。
});
// 这种也是拷贝
connect(thr1, &QThread::started, thr1, [a, test, mywork](){
qDebug() << a << test;
mywork->dowork2();
});
2. 需要修改原变量 → 用 [&](引用捕获)
必须保证:变量生命周期 > Lambda 执行时间,否则会崩溃
connect(thr1, &QThread::started, thr1, [&](){
a = 100; // 修改原变量
test = "ok";
});
// 还有一种,invoke触发 和 //mywork->dowork2();//主线程执行
// 想实现的类似, invoke触发的//是子线程执行
QMetaObject::invokeMethod(
myUart, // 1. 目标:子线程里的 uartWork
"sendData", // 2. 要调用的槽函数名字(必须加引号)
Qt::QueuedConnection, // 3. 固定:跨线程队列调用
Q_ARG(QByteArray,sendData) // 4. 参数1:类型+值
);
*/
QObject::connect(thr1, &QThread::started, mywork, &worker::dowork1); //第一槽函数
QObject::connect(mywork, &worker::singalwork, mywork, &worker::dowork3); //第三槽函数
//mywork->dowork2();//主线程执行
//QObject::connect(thr1, &QThread::started, mywork, &worker::dowork2); //子线程执行
// 线程的moveToThread,把mywork的所有槽函数都转入线程,所以,信号singalwork触发也是,dowork3,也是线程执行
thr1->start();
// 相当于 在这里答应ThreadID
mywork->test();
qDebug() << "MainWindow 成员函数ThreadID:"<<QThread::currentThreadId();
//发送自定义信号
emit mywork->singalwork();
}