qt线程动态回调被调类中的函数

本文介绍如何封装一个Qt线程,使其能在不同类中调用,并使用Lambda表达式实现在线程中回调被调用类的成员函数。通过在VS2010+Win7+Qt5.40环境下编译验证,适用于需要在线程中灵活调用类方法的场景。

1.需求

要求封装一个qt线程能在不同类中调用,并能回调被调用类中的函数

2.解决

尝试多种方法,最终决定采用动态加载lamda表达式的方法解决

3.代码

catthread.h
#ifndef CATTHREAD_H
#define CATTHREAD_H
#include <QtCore/QThread>
#include <functional>

class catthread : public QThread
{
    Q_OBJECT

public:
    catthread(QObject *parent);
    ~catthread(){}

public:
    void setCallback(std::function<void(void)> func); 

protected:
    virtual void run();

private:
     std::function<void(void)> m_func;
};

#endif // CATTHREAD_H
catthread.cpp
#include "catthread.h"

catthread::catthread(QObject *parent)
    : QThread(parent)
{
    m_func = nullptr;
}

void catthread::run()
{
    if (m_func != nullptr)
        m_func();
}

void catthread::setCallback(std::function<void(void)> func)
{
    m_func = func;
}
gui中调用和回调
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QtWidgets/QMainWindow>
#include "ui_mythread.h"
#include "catthread.h"

class mythread : public QMainWindow
{
    Q_OBJECT

public:
    mythread(QWidget *parent = 0);
    ~mythread();

private slots:
    void on_func1Button_clicked();
    void on_func2Button_clicked();
    void on_func3Button_clicked();
    void thread_finish();

public:
    void func1();
    void func2();
    void func3();

private:
    Ui::mythreadClass ui;
    catthread m_thread;

public:
    int m_nvalue;
};

#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
#include <QMessageBox>

mythread::mythread(QWidget *parent)
    : QMainWindow(parent),m_thread(parent)
{
    ui.setupUi(this);
    connect(&m_thread, SIGNAL(finished()), this, SLOT(thread_finish()));
}

mythread::~mythread()
{

}

void mythread::func1()
{
    m_nvalue = 10;
}

void mythread::func2()
{
    m_nvalue = 20;
}

void mythread::func3()
{
    m_nvalue = 30;
}

void mythread::on_func1Button_clicked()
{
    if (!m_thread.isRunning())
    {
        auto func = [&](){func1();};
        m_thread.setCallback(func);
        m_thread.start();
    }
}

void mythread::on_func2Button_clicked()
{
    if (!m_thread.isRunning())
    {
        auto func = [&](){func2();};
        m_thread.setCallback(func);
        m_thread.start();
    }
}

void mythread::on_func3Button_clicked()
{
    if (!m_thread.isRunning())
    {
        auto func = [&](){func3();};
        m_thread.setCallback(func);
        m_thread.start();
    }
}

void mythread::thread_finish()
{
    QString strMsg("");
    strMsg = QString("%1").arg(m_nvalue);
    QMessageBox::information(this, "msg", strMsg);
}
main.cpp
#include "mythread.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    mythread w;
    w.show();
    return a.exec();
}

4.备注

1.在vs2010+win7+qt5.40下编译通过
2.传递不同类成员函数时可以采用lamda表达式实现
Qt中,在主函数`main()`中使用线程回调,通常涉及到异步操作,特别是处理耗时任务或者避免阻塞UI线程。当你在一个新线程中启动一个长时间运行的任务,例如网络请求、文件I/O等,可以创建一个`QThread`并在线程对象上注册一个槽函数作为该任务完成后将结果返回给主线程回调。 以下是一个简单的示例: ```cpp #include <QApplication> #include <QThread> #include <QFuture> class Worker : public QObject { public: Worker(QObject *parent = nullptr) : QObject(parent) { } Q_INVOKABLE void runTask(int value) { int result = someExpensiveCalculation(value); emit taskCompleted(result); } signals: void taskCompleted(int result); private: int someExpensiveCalculation(int value) { /* ... */ } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); // 创建Worker对象并在新线程中运行 Worker worker; QThread thread(&worker); worker.moveToThread(&thread); // 确保工作在新线程上 connect(&worker, &Worker::taskCompleted, this, &QApplication::postEvent, Qt::QueuedConnection); // 设置回调 thread.start(); // 开启新线程 thread.quit(); // 启动后立即停止,让线程在runTask执行完后再退出 thread.wait(); // 阻塞主线程直到任务完成 // 主线程接收到taskCompleted信号后,通过回调函数处理结果 int result = qApp->eventDispatcher()->processEvents(QEventLoop::ExcludeUserInputEvents); qDebug() << "Task completed with result: " << result; return app.exec(); } ``` 在这个例子中,`someExpensiveCalculation`代表了耗时的操作,`taskCompleted`信号发出后,主线程回调函数就会被执行。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值