私のメインウィンドウには、中央にQGraphicsViewを備えたサイドGUIがあり、GUIによってトリガーされ、QGraphicsViewに影響を与えるさまざまな計算を行うロジッククラスがあります。一部の計算は重いためGUIがスリープ状態になり、QProgressBarやその他のQtアイテムがあり、計算中にデータが提供されるため、GUIプロセスがスリープ状態になると、これらのアイテムは更新された結果を表示するのは次の場合のみです。プロセスが終了しました。ロジッククラスとUIが同じプロセスであるため、理解しています。
私はこれを修正しようとしていました:私の古い質問と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();
}