#ifndef ONETHREAD_H #define ONETHREAD_H #include #include #include #include /** * 这个类提供了一种方便的线程调用方法,可以直接用信号将需要放入新线程 * 运行的函数传递给这个类,然后就会在槽函数中运行这个函数 * 使用方法: * 1. 创建一个OneThread对象,传入一个QThread对象,或者不传入,会自动创建一个QThread对象 * 2. 使用addTask或者addTaskRunOne添加任务,addTask会进入循环,addTaskRunOne只会执行一次 * 3. 不使用addTask,直接使用bindTask绑定函数和参数,手动触发信号,注意,触发信号前,要先开启子线程getThread()->start(); * * 使用示例: * 1、非成员函数 * void func(int a, int b) { std::cout << a + b << std::endl; } * thread.add_task(func, 1, 2); * 2、成员函数 * void A::func(int a, int b) { std::cout << a + b << std::endl; } * A a; * thread.add_task(&A::func, &a, 1, 2); */ class OneThread : public QObject { Q_OBJECT public: explicit OneThread(QThread* thread, QObject* parent = nullptr); explicit OneThread(QObject* parent = nullptr); ~OneThread(); /* 获取子线程 */ QThread* getThread() const { return m_thread; } /* 停止子线程 */ void stopThread() { m_threadRunning = false; } /* 添加任务,开启子线程,这个会进入循环,不会退出,调用stopThread会停止线程 */ template void addTask(F&& f, Args&&... args) { if(!m_thread->isRunning()) { m_thread->start(); } std::function task = std::bind(std::forward(f), std::forward(args)...); emit signal_runTask(task); } /* 添加任务,开启子线程,这里只会执行一次 */ template void addTaskRunOne(F&& f, Args&&... args) { if(!m_thread->isRunning()) { m_thread->start(); } std::function task = std::bind(std::forward(f), std::forward(args)...); emit signal_runTaskRunOne(task); } /* 将函数与参数绑定 */ template std::function bindTask(F&& f, Args&&... args) { return std::bind(std::forward(f), std::forward(args)...); } signals: void signal_runTask(std::function func); void signal_runTaskRunOne(std::function func); private slots: void do_runTask(std::function func); void do_runTaskRunOne(std::function func); private: bool m_threadRunning = false; QThread* m_thread = nullptr; QTimer m_timer; /* 定时器 */ std::function m_func; /* 运行的函数 */ }; #endif // ONETHREAD_H