What is the proper way to separate the view layer from the logic layer in QT?
-
My mainwindow have a side GUI with a QGraphicsView in the center, there is a logic class which make different calculations which triggered by the GUI and effects the QGraphicsView. Some of the calculations are heavy which make the GUI go to sleep, there is a QProgressBar and some other Qt items which provides some data while the calculations are been made, so when the GUI process goes to sleep those items show there updated result only when the process has finished. I understand that it because the logic class and the UI are under the same process,
I was trying to correct this by doing: "Maya's Programming Blog":http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
But I came to understanding that this method is not sufficient to my code as I have several methods that run heavy calculations and some of them returning values. Maya's method talking about doing something like this:
@connect(thread, SIGNAL(started()), worker, SLOT(process()));...thread->start();@, but in my code there is no single main process but many, so if I want to work in that way, from what I understand I need to create a thread before each process method, move the logic class to this thread and than connect the process method with the thread start method, which not sounds to me as the proper way to do this.
So I ask for a way to fully separate the logic layer from the view layer, so any method which invoked the logic layer will run on a different process (which is the same for all logic class methods), so the view layer won't go to sleep.
Note: there is no problems of synchronicity, when a calculation been made it's the only one which work at a time.
An example of my problem (GUI go to sleep):
@#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include "Logic/worker.h"namespace Ui {
class MainWindow;
#define MAXLOOP 1000000
}class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();signals:
private slots:
void startProcessing1(); void processing1Done(); void on_pushButton_exit_clicked();
private:
Ui::MainWindow *ui;};
#endif // MAINWINDOW_H
/////////////////////////////////////////////////////////////////////////////////
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QThread"MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);ui->progressBar_1->setVisible(false); ui->progressBar_1->setMaximum(MAXLOOP); ui->progressBar_1->setMinimum(0); connect(ui->pushButton_1, SIGNAL(clicked()), this, SLOT(startProcessing1()));
}
MainWindow::~MainWindow()
{
delete ui;
}void MainWindow::startProcessing1()
{
ui->progressBar_1->setVisible(true);Worker *worker = new Worker(MAXLOOP); QThread* thread = new QThread; worker->moveToThread(thread); connect(worker, SIGNAL(finished1Hide()), this, SLOT(processing1Done())); connect(worker, SIGNAL(changePbar1(int)), ui->progressBar_1, SLOT(setValue(int))); connect(thread, SIGNAL(started()), worker, SLOT(process1())); connect(worker, SIGNAL(finished1()), thread, SLOT(quit())); connect(worker, SIGNAL(finished1()), worker, SLOT(deleteLater())); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); thread->start();
}
void MainWindow::processing1Done()
{
ui->progressBar_1->setVisible(false);
}void MainWindow::on_pushButton_exit_clicked()
{
this->close();
}/////////////////////////////////////////////////////////////////////////////////
#ifndef WORKER_H
#define WORKER_H#include <QObject>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(int maxLoop, QObject *parent = 0);signals:
void finished1(); void finished1Hide(); void changePbar1(int val);
public slots:
void process1();
private:
int m_maxLoop;
};
#endif // WORKER_H
/////////////////////////////////////////////////////////////////////////////////
#include "worker.h"
Worker::Worker(int maxLoop, QObject *parent) :
QObject(parent)
{
m_maxLoop = maxLoop;
}void Worker::process1()
{
int sum = 0;
for(int i = 0; i < m_maxLoop; ++i)
{
emit changePbar1(i);
sum += i;
}
emit finished1();
emit finished1Hide();
}@