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

C++ 在QT中,将视图层与逻辑层分开的正确方法是什么?,c++,qt,qthread,qprogressbar,C++,Qt,Qthread,Qprogressbar,我的主窗口有一个侧面的GUI,中间有一个QGraphicsView,有一个逻辑类,它进行不同的计算,由GUI触发并影响QGraphicsView。 一些计算很繁重,这会使GUI进入睡眠状态,有一个QProgressBar和一些其他Qt项,在进行计算时提供一些数据,因此当GUI进程进入睡眠状态时,这些项仅在进程完成时才会显示更新的结果。我理解这是因为逻辑类和UI在同一个过程中 我试图通过这样做来纠正这个问题:并且 但我逐渐认识到,这两种方法都不足以支持我的代码,因为我有几个方法运行大量计算,其中一

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

我试图通过这样做来纠正这个问题:并且

但我逐渐认识到,这两种方法都不足以支持我的代码,因为我有几个方法运行大量计算,其中一些方法返回值。他们都在谈论这样做:
connect(线程、信号(start())、worker、SLOT(进程())大于
线程->开始(),但在我的代码中没有单一的主进程,因此,如果我想以这种方式工作,根据我的理解,我需要在每个进程方法之前创建一个线程,将逻辑类移动到此线程,然后将进程方法与线程开始方法连接,我认为这不是正确的方法

因此,我要求提供一种将逻辑层与视图层完全分离的方法,以便调用逻辑层的任何方法都将在不同的进程上运行(这对于所有逻辑类方法都是相同的),因此视图层不会进入睡眠状态

注:不存在同步性问题,当进行计算时,它是一次唯一起作用的

我的问题的一个例子:

#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();
}
\ifndef主窗口
#定义主窗口
#包括
#包括“Logic/worker.h”
名称空间用户界面{
类主窗口;
#定义MAXLOOP 1000000
}
类主窗口:公共QMainWindow
{
Q_对象
公众:
显式主窗口(QWidget*parent=0);
~main窗口();
信号:
专用插槽:
void startProcessing1();
void processing1Done();
单击按钮退出时无效();
私人:
Ui::MainWindow*Ui;
};
#endif//main窗口
/////////////////////////////////////////////////////////////////////////////////
#包括“mainwindow.h”
#包括“ui_main window.h”
#包括“QThread”
主窗口::主窗口(QWidget*父窗口):
QMainWindow(父级),
用户界面(新用户界面::主窗口)
{
用户界面->设置用户界面(此);
ui->progressBar_1->setVisible(假);
ui->progressBar_1->setMaximum(MAXLOOP);
ui->progressBar_1->setMinimum(0);
连接(用户界面->按钮_1,信号(点击()),此插槽(启动处理1());
}
MainWindow::~MainWindow()
{
删除用户界面;
}
void主窗口::startProcessing1()
{
ui->progressBar_1->setVisible(真);
工人*工人=新工人(MAXLOOP);
QThread*thread=新的QThread;
辅助线程->移动到线程(线程);
连接(工作、信号(finished1Hide())、此、插槽(processing1Done());
连接(工作,信号(changePbar1(int)),ui->progressBar_1,插槽(setValue(int)));
连接(线程、信号(已启动())、工作线程、插槽(进程1());
连接(工作、信号(finished1())、线程、插槽(退出());
连接(工作,信号(finished1()),工作,插槽(deleteLater());
连接(线程、信号(finished())、线程、插槽(deleteLater());
线程->开始();
}
void主窗口::正在处理1done()
{
ui->progressBar_1->setVisible(假);
}
无效主窗口::在按钮上单击退出按钮()
{
此->关闭();
}
/////////////////////////////////////////////////////////////////////////////////
#ifndef工人
#定义WORKER_H
#包括
班级工作人员:公共QObject
{
Q_对象
公众:
显式工作者(int-maxLoop,QObject*parent=0);
信号:
无效完成1();
void finished1Hide();
无效更改BAR1(int val);
公众时段:
void process1();
私人:
int m_maxLoop;
};
#endif//WORKER\u H
/////////////////////////////////////////////////////////////////////////////////
#包括“worker.h”
Worker::Worker(int-maxLoop,QObject*父对象):
QObject(父对象)
{
m_maxLoop=maxLoop;
}
void Worker::process1()
{
整数和=0;
对于(int i=0;i
tags(第三个)中有一个答案),但我尝试了qthread,它不起作用,因为我没有一个主进程,但manyI已经将我的示例更改为一个真实的示例,这表明即使只有一个线程和一个连接的进程,主窗口(GUI)也会进入睡眠状态
m\u worker->moveToThread(thread)不强制工作程序的代码在单独的线程中运行。你应该在重载
run
method中为QThread子类并调用worker函数我读到子类QThread不是这样做的,我可以将线程启动信号连接到process1插槽,但我认为必须为每个进程(1,2…)执行,这听起来很混乱