在QT中将视图层与逻辑层分开的正确方法是什么?

时间:2013-03-16 06:38:35

标签: c++ qt qthread qprogressbar

我的主窗口有一个侧面GUI,中间有一个QGraphicsView,有一个逻辑类可以进行不同的计算,这些计算由GUI触发并影响QGraphicsView。 一些计算很重,使得GUI进入休眠状态,有一个QProgressBar和一些其他Qt项目在计算完成时提供了一些数据,因此当GUI进程进入休眠状态时,这些项目仅显示更新结果这个过程已经完成。我理解这是因为逻辑类和UI处于同一个过程中,

我试图通过执行以下操作来纠正此问题:My old questionMaya's Programming Blog

但我开始明白,我的代码都不够,因为我有几个运行繁重计算的方法,其中一些返回值。两者都在谈论做这样的事情: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();
}

0 个答案:

没有答案