Как правильно отделить уровень представления от уровня логики в QT?

У моего основного окна есть боковой графический интерфейс с QGraphicsView в центре, есть логический класс, который выполняет различные вычисления, которые запускаются графическим интерфейсом и влияют на QGraphicsView. Некоторые из вычислений являются тяжелыми, что заставляет графический интерфейс переходить в спящий режим, есть QProgressBar и некоторые другие элементы Qt, которые предоставляют некоторые данные во время выполнения вычислений, поэтому, когда процесс графического интерфейса переходит в спящий режим, эти элементы показывают обновленный результат только тогда, когда процесс закончился. Я понимаю, что это потому, что класс логики и пользовательский интерфейс находятся в одном процессе,

Я пытался исправить это, выполнив: Мой старый вопрос и Блог программирования Maya

Но я пришел к пониманию, что и того, и другого недостаточно для моего кода, поскольку у меня есть несколько методов, выполняющих тяжелые вычисления, а некоторые из них возвращают значения. Оба говорят о том, чтобы сделать что-то вроде этого: connect(thread, SIGNAL(started()), worker, SLOT(process()));..., чем thread->start();, но в моем коде нет единого основного процесса, поэтому, если я хочу работать таким образом, насколько я понимаю, мне нужно создать поток перед каждым методом процесса, переместите логический класс к этому потоку, а затем соединить метод процесса с методом запуска потока, что мне не кажется правильным способом сделать это.

Поэтому я прошу способ полностью отделить уровень логики от уровня представления, чтобы любой метод, который вызвал уровень логики, работал в другом процессе (который одинаков для всех методов класса логики), поэтому уровень представления не будет идти спать.

Примечание: нет проблем с синхронностью, когда вычисление произведено, единственное, что работает за один раз.

Пример моей проблемы:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "Logic/worker.h"

namespace Ui {
class MainWindow;
#define MAXLOOP 1000000
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    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();
}

person GoldenAxe    schedule 16.03.2013    source источник
comment
У вас есть ответ в тегах (третий)))   -  person borisbn    schedule 16.03.2013
comment
Но я пробовал qthread, это не сработало, потому что у меня нет одного основного процесса, а много   -  person GoldenAxe    schedule 16.03.2013
comment
Я изменил свой пример на реальный, который показывает, что даже с одним потоком и только одним подключенным процессом главное окно (GUI) переходит в спящий режим.   -  person GoldenAxe    schedule 16.03.2013
comment
m_worker->moveToThread(thread); не заставляет рабочий код выполняться в отдельном потоке. Вы должны создать подкласс QThread и вызвать функцию рабочего в перегруженном run методе   -  person borisbn    schedule 17.03.2013
comment
Я читал, что подкласс QThread - это не способ сделать это, я мог бы подключить сигнал запуска потока к слоту process1, но я думаю, что это нужно будет сделать для каждого процесса (1,2 ...), и это звучит беспорядочно   -  person GoldenAxe    schedule 17.03.2013
comment
Ты прав. Подключение к сигналу запуска потока - более правильный способ, но я не вижу его в вашем коде   -  person borisbn    schedule 17.03.2013
comment
Я изменяю пример на минимальный пример, включая использование сигнала запуска потока, и графический интерфейс все еще спит, хотя, насколько я понимаю, рабочий поток находится в другом потоке от основного окна   -  person GoldenAxe    schedule 17.03.2013