前面介绍了线程池在逻辑层中的实现以及在qml应用中的使用,由于qml全局可见;所以就可以直接把逻辑层的WorkManager对象给qml调用就可以了。这次主要介绍逻辑层与widgets这种UI交互。
所有的图形控件都是基于widgets的,所以我们要从widgets入手增加自己的接口;如下
class BaseWidget : public QWidget
{
Q_OBJECT
public:
explicit BaseWidget(WidgetManager *wm,QWidget *parent = nullptr):_wmager(wm),QWidget(parent){
wm->registerWidget(this); //将自己注册到WidgetManager便于统一管理
}
virtual void setUserStyle(WidgetManager::SkinStyle style) = 0; //设置皮肤
virtual inline WidgetManager::SkinStyle userStyle(){ //访问当前使用皮肤
return _wmager->currentStyle();
}
virtual inline BLL::Worker* getWoker(QString name){ //根据名字获取一个死循环运行的Worker
return _wmager->workerManager()->getWorker(name.toStdString());
}
virtual inline void startWorker(BLL::Worker*w, int threadCount = 1){ //启动一个Worker
return _wmager->workerManager()->startWorker(w,threadCount);
}
virtual inline WidgetManager* widgetManger() const{return _wmager;} //返回自己所属的WidgetManager
private:
WidgetManager *_wmager = nullptr;
};
下面是WidgetManager,它主要将所有的Widgets管理起来,并和WorkManager有一个接口。
class WidgetManager
{
public:
enum SkinStyle{
Danyahei
};
virtual void registerWidget(BaseWidget* baseW) = 0; //注册一个Widget
virtual void notifyUserStyle(SkinStyle style) = 0; //通知所有的Widget当前皮肤变化
virtual SkinStyle currentStyle() const = 0; //返回当前使用皮肤
virtual inline void setWorkerManager(BLL::WorkerManager *workerM){ //设置使用的WorkManager
_workerM = workerM;
}
virtual inline BLL::WorkerManager* workerManager(){return _workerM;} //返回当前使用的WorkManager
private:
BLL::WorkerManager *_workerM = nullptr;
};
下面是程序初始化中的应用,和qml应用大体类似;只是Widgets控件是以c++类的形式创建,有一些不一样
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
BLL::BaseWorkerManager *workerManager = new BLL::BaseWorkerManager(QThreadPool::globalInstance()); //创建WorkManager
BLL::RunForeverWorker *worker = new BLL::RunForeverWorker; //创建要启用的死循环Worker,单次运行的Worker在使用的地方创建,用WorkManager启动startWorker()就可以了,执行完会自动释放Worker
workerManager->installWorker("foreverWorker",worker); //将创建的Worker添加到WorkManager
BaseWidgetManager *widgetManger = new BaseWidgetManager; //创建WidgetManager
widgetManger->setWorkerManager(workerManager); //设置WidgetManager使用的WorkManager
Widget w(widgetManger); //创建主窗口
w.show();
workerManager->startWorker(worker); //启动worker
QObject::connect(&a,&QApplication::lastWindowClosed,[workerManager]{ //当最后一个窗口关闭时释放workerManager,它会释放worker
workerManager->deleteLater();
});
return a.exec();
}
这样在具体的Widget子类中都要继承接口,就可以统一随时响应应用皮肤,随时与逻辑层进行交互,随时可以启用一个单次执行任务来完成一个工作,直接获取Worker类对象并转换为子类,连接它的信号就能将结果设置到UI了
class Widget : public BaseWidget
{
Q_OBJECT
public:
Widget(WidgetManager* wm,QWidget *parent = 0);
~Widget();
void setUserStyle(WidgetManager::SkinStyle style) override;
};
在cpp中像下面这样就能轻松的与逻辑层交互了
Widget::Widget(WidgetManager *wm, QWidget *parent)
: BaseWidget(wm,parent)
{
BLL::RunForeverWorker *worker = dynamic_cast(getWoker("foreverWorker")); //得到worker
connect(worker,SIGNAL(sigResponse(QVariant)),this,SLOT(shoResonse(QVariant))); //处理响应结果
worker->requestData(); //记woker干的事
}
Widget::~Widget()
{
}
void Widget::setUserStyle(WidgetManager::SkinStyle style)
{
}
本次介绍完毕,下次将会介绍逻辑层与数据访问层之间的交互。