工作器/控制器多线程和接口类
Worker/Controller multi-threading and interface class
实现,因为在我看来它是多线程对象的接口类。当窗口关闭时,除了这一行之外,一切正常。
connect(_controller, &IClass::finished, this, [] { qDebug() << "finished"; });
- 我是否重新发明轮子?
- 为什么删除对象时(关闭窗口时(不发出
Controller::finished
信号? - 是否可以将信号设为私有以不创建
Private Controller
? - 我需要使控制器成为
IClass
的后代吗? - 提示和建议
代码示例:
主窗口.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QDebug>
#include <QMainWindow>
#include <QThread>
class Worker1;
class Worker2;
class IClass : public QObject{
Q_OBJECT
protected:
IClass(QObject *parent = nullptr) : QObject(parent) { }
public:
enum class Types { Worker1, Worker2, };
static IClass* CreateInstance(Types t, QObject *parent = nullptr);
signals:
void started();
void finished();
public slots:
virtual void f1() = 0;
virtual void f2(int i) = 0;
virtual void f3(int x, double y) = 0;
virtual void start() = 0;
virtual void stop() = 0;
};
class PrivateController : public QObject {
Q_OBJECT
IClass *_w;
public:
PrivateController(IClass *c, QObject *parent = nullptr) : QObject(parent), _w(c) {
connect(this, &PrivateController::f1, _w, &IClass::f1);
connect(this, &PrivateController::f2, _w, &IClass::f2);
connect(this, &PrivateController::f3, _w, &IClass::f3);
connect(this, &PrivateController::stop, _w, &IClass::stop);
}
~PrivateController() override;
void callF1() { emit f1(); }
void callF2(int i) { emit f2(i); }
void callF3(int x, double y) { emit f3(x, y); }
void callStop() { emit stop(); }
signals:
void f1();
void f2(int i);
void f3(int x, double y);
void stop();
};
class Controller : public IClass {
Q_OBJECT
public:
Controller(IClass::Types t, QObject *parent = nullptr)
: IClass(parent), _w(CreateInstance(t)), _signals(_w) {
connect(_w, &IClass::started, this, &IClass::started);
connect(_w, &IClass::finished, this, &IClass::finished);
}
~Controller() override;
public slots:
void f1() override { _signals.f1(); }
void f2(int i) override { _signals.f2(i); }
void f3(int x, double y) override { _signals.f3(x, y); }
void start() override {
QThread *th = new QThread;
_w->moveToThread(th);
connect(th, &QThread::started, _w, &IClass::start);
connect(_w, &IClass::finished, th, &QThread::quit);
connect(_w, &IClass::finished, th, &QThread::deleteLater);
connect(_w, &IClass::finished, _w, &IClass::deleteLater);
th->start();
qDebug() << "Controller::start";
}
void stop() override {
_signals.stop();
qDebug() << "Controller::stop";
}
protected:
IClass *_w;
PrivateController _signals;
};
class Worker1 : public IClass {
Q_OBJECT
public:
Worker1(QObject *parent = nullptr)
: IClass(parent) {
// some code
}
public slots:
void f1() override {
qDebug() << "Worker1::f1";
}
void f2(int i) override {
qDebug() << "Worker1::f2" << i;
}
void f3(int x, double y) override {
qDebug() << "Worker1::f3" << x << y;
}
void start() override {
emit started();
qDebug() << "Worker1::start";
}
void stop() override {
emit finished();
qDebug() << "Worker1::stop";
}
protected:
// some code
};
class Worker2 : public IClass {
Q_OBJECT
public:
Worker2(QObject *parent = nullptr)
: IClass(parent) {
// some code
}
public slots:
void f1() override {
qDebug() << "Worker2::f1";
}
void f2(int i) override {
qDebug() << "Worker2::f2" << i;
}
void f3(int x, double y) override {
qDebug() << "Worker2::f3" << x << y;
}
void start() override {
emit started();
qDebug() << "Worker2::start";
}
void stop() override {
emit finished();
qDebug() << "Worker2::stop";
}
protected:
// some code
};
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
IClass *_controller;
};
#endif // MAINWINDOW_H
主窗口.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
_controller(new Controller(IClass::Types::Worker2, this))
{
ui->setupUi(this);
connect(_controller, &IClass::started, this, [] { qDebug() << "started"; });
connect(_controller, &IClass::finished, this, [] { qDebug() << "finished"; });
_controller->start();
_controller->f1();
_controller->f2(2);
_controller->f3(3, 4.4);
// _controller->stop();
}
MainWindow::~MainWindow() { delete ui; }
PrivateController::~PrivateController() { qDebug() << "~PrivateController()"; }
IClass *IClass::CreateInstance(IClass::Types t, QObject *parent) {
switch(t) {
case Types::Worker1: { return new Worker1(parent); }
case Types::Worker2: { return new Worker2(parent); }
}
}
Controller::~Controller() { _signals.callStop(); }
输出:
Controller::start
Worker2::start
Worker2::f1
Worker2::f2 2
Worker2::f3 3 4.4
started
~PrivateController()
Worker2::stop
不要发出finished
.
关于问题#2:尝试对main
进行此编辑:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
int r = a.exec();
qDebug() << "event loop gone ...";
return r;
}
立即检查您的输出。如您所见,当发出finished
信号时,您的主线程不再有事件循环,因此不会捕获信号(因为它来自另一个线程(。
为了进一步证明这一点,请在窗口中添加一个按钮,并有一个如下所示的clicked
槽:
void MainWindow::on_pushButton_clicked()
{
_controller->stop();
qApp->processEvents();
qApp->exit();
}
这样,您退出应用程序,但只有在处理完所有排队的事件之后(即排队的信号被传递......
坦率地说,关于你问的其他一切:即使是赏金问题,它似乎也很宽泛。无论如何,希望我有所帮助。
相关文章:
- 在C++中使用cURL和多线程
- 多线程双缓冲区
- 为什么我的多线程作业队列崩溃
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- 为什么一个向量上的多线程操作很慢
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 全局变量 多读取器 一个写入器多线程安全?
- boost::文件系统::recursive_directory_iterator多线程安全
- 如何阻止TensorFlow的多线程
- 如何在多线程中正确使用unique_ptr进行多态性?
- 并发/多线程:是否可以以这种方式生成相同的输出?
- sigwait() 在多线程程序中不起作用
- 多线程程序中出现意外的内存泄漏
- 静态 constexpr 类成员变量对多线程读取是否安全?
- 多线程比没有线程C++慢
- 具有 C++11 多线程的特征库
- 工作器/控制器多线程和接口类
- 使用本机接口的多个java线程与多线程本机的单个java线程相比
- 在多线程应用程序中更新GTK接口的最佳方法是什么?