我需要加载一个大文件,它是一个.zip存档,包含两个文件:config和data。加载进度包括三个阶段:解析配置,解析数据,将数据映射到更合适的格式。我需要在一个单独的线程中完成它。此外,我需要在进度对话框中显示进度和阶段,其中包含舞台QLabel和当前舞台进度的QProgressBar。
在对QtConcurrent进行一些研究之后,我将使用这样的代码:
class OscillogramLoader : public QtConcurrent::ThreadEngine<Data>
{
public:
OscillogramLoader(QString filename);
protected:
QtConcurrent::ThreadFunctionResult threadFunction() override;
private:
QString m_filename;
};
QtConcurrent::ThreadFunctionResult OscillogramLoader::threadFunction()
{
futureInterfaceTyped()->setProgressRange(0, 50);
for (int i = 0; i < 50; ++ i)
{
if (isCanceled())
break;
futureInterfaceTyped()->setProgressValueAndText(i, "Parsing config");
QThread::msleep(100); // Real work will be here
}
futureInterfaceTyped()->setProgressRange(50, 250);
for (int i = 0; i < 200; ++ i)
{
if (isCanceled())
break;
futureInterfaceTyped()->setProgressValueAndText(50 + i, "Map data");
QThread::msleep(50); // Real work will be here
}
futureInterfaceTyped()->setProgressRange(250, 350);
for (int i = 0; i < 100; ++ i)
{
if (isCanceled())
break;
futureInterfaceTyped()->setProgressValueAndText(250 + i, "Map data");
QThread::msleep(80); // Real work will be here
}
reportResult(new OscillogramData()); // returning loaded data
return QtConcurrent::ThreadFinished;
}
....
QFutureWatcher<OscillogramData>* watcher = new QFutureWatcher<OscillogramData>();
QObject::connect(watcher, &QFutureWatcher<OscillogramData>::started, ...);
QObject::connect(watcher, &QFutureWatcher<OscillogramData>::progressRangeChanged, ...);
QObject::connect(watcher, &QFutureWatcher<OscillogramData>::progressTextChanged, ...);
QObject::connect(watcher, &QFutureWatcher<OscillogramData>::progressValueChanged, ...);
QObject::connect(watcher, &QFutureWatcher<OscillogramData>::finished, [=](){
OscillogramData data = watcher->result();
showData(&data);
watcher->deleteLater();
});
watcher->setFuture(QFuture<OscillogramData>(
QtConcurrent::startThreadEngine(new OscillogramLoader("/home/example/test1.zip"))));
....
可以吗?
我的旧版本的loader类继承自QThread,具有progressChanged,done,failure信号和overrided run方法。它比以前的代码更好还是更差?
class OscillogramLoader : public QThread
{
Q_OBJECT
public:
explicit OscillogramLoader(QString filename, QObject* parent = nullptr);
QString filename() const;
bool isCanceled() const;
public slots:
void cancel();
signals:
void progressChanged(QString stage, double parcent);
void done(QString filaname, QSharedPointer<OscillogramData> data);
void failure(LoadFailureException exception);
protected:
void run() override;
private:
QString m_filename;
bool m_cancelled;
};