项目【QT5.13频谱分析软件】(三)——线程获取Excel表格数据

 

​读取Excel表格数据,当数据量很大时,如果直接读取会造成ui界面卡顿,所以需要建立线程,在线程里读取数据。

一、建立继承QThread的读取数据类

建立读取数据线程,重写run()函数

.h文件如下:

#ifndef THREADREADDATA_H
#define THREADREADDATA_H
​
#include <QThread>
#include <QWaitCondition>
​
#include "ui_mainwindow.h"
​
class threadReadData : public QThread
{
    Q_OBJECT
​
public:
    explicit threadReadData(QObject *parent = nullptr);
    ~threadReadData() override;
​
    void  handleFunc();
​
    QString filename;
​
signals:
    void  request(const QVariant var);
​
private:
    void run() override;
};
​
#endif // THREADREADDATA_H

.cpp文件如下:

#include "threadreaddata.h"
​
#include <QFileDialog>
#include <QAxObject>
#include <QStandardPaths>
#include <QDebug>
​
threadReadData::threadReadData(QObject *parent):
    QThread(parent)
{
​
}
​
threadReadData::~threadReadData()
{
    quit();
}
​
void threadReadData::handleFunc()
{
    if(!isRunning())
        start();
}
​
void threadReadData::run()
{
    //读取数据
    QAxObject *excel = new QAxObject();//建立excel操作对象
    excel->setControl("Excel.Application");//连接Excel控件
    excel->setProperty("Visible", false);//显示窗体看效果,选择ture将会看到excel表格被打开
    excel->setProperty("DisplayAlerts", true);//显示警告看效果
    QAxObject *workbooks = excel->querySubObject("WorkBooks");//获取工作簿(excel文件)集合
    qDebug()<<"filename:"<<filename;
    workbooks->dynamicCall("Open(const QString&)", filename);//打开刚才选定的excel
    QAxObject *workbook = excel->querySubObject("ActiveWorkBook");
    QAxObject *worksheet = workbook->querySubObject("WorkSheets(int)",1);
    QAxObject *usedRange = worksheet->querySubObject("UsedRange");//获取表格中的数据范围
​
    QVariant var = usedRange->dynamicCall("Value"); 
​
    workbook->dynamicCall( "Close(Boolean)", false );
    excel->dynamicCall( "Quit(void)" );
    delete excel;//关闭excel
    emit request(var);
}

代码第39行,新建QVariant容器,将所有的数据读取到QVariant容器中保存,数据读取完毕后,关闭Excel表格,并将保存的数据发射出去。

 

二、实现【打开文件按钮】槽函数

通过QFileDialog::getOpenFileName()获取Excel文件名称,使用contains()函数判断文件类型是否正确,如果正确则启动数据读取线程函数m_thread.handleFunc()。

读取数据时,更新进度槽函数,当读取至99%时,等待数据读取完毕,然后进度条更新至100%。

读取数据槽函数如下:

void MainWindow::on_actionOpen_triggered()
{
    QString FileName = QFileDialog::getOpenFileName(this,
                                                    tr("文件对话框"),
                                                    QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
                                                    tr("ALL files (*);;Excel Files(*.xlsx);;Text Files(*.txt)"));
//    qDebug() << "filename:" << FileName;
    ui->labelPath->setText(FileName);
    m_thread.filename = FileName;
    if(FileName.contains(".xlsx", Qt::CaseSensitive) != true)
    {
        qDebug()<<"地址错误!";
        QMessageBox::information(nullptr, "地址错误", "地址错误,\n请重新选择!",
                                 QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
        return;
    }
​
    progressBarTimer.start();
​
    ui->actionOpen->setEnabled(false);
    ui->actionStart->setEnabled(false);
    ui->actionPause->setEnabled(false);
    ui->actionStop->setEnabled(false);
    ui->actionForward->setEnabled(false);
    ui->actionBackward->setEnabled(false);
    ui->actionReset->setEnabled(false);
    m_thread.handleFunc();
​
}

进度条槽函数如下:

void MainWindow::on_progressBar_valueChanged()
{
    ui->progressBar->setValue(progressBarValue);
    if(progressBarValue >= 100)
    {
        progressBarTimer.stop();
        progressBarValue = 0;
        ui->actionStart->setEnabled(true);
        ui->pushButtonSource->setEnabled(true);
        return;
    }
    if(progressBarValue < 99)
    {
        progressBarValue += 1;
    }
}

这样就实现了线程读取Excel数据,ui界面不会卡顿。

 

关注微信公众号 小白技术栈 | lakalako,获取更多的内容,欢迎大家关注哦!

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
您好!要从子线程获取数据并更新QT的TabView,您可以使用以下步骤: 1. 创建一个自定义的QObject子类,用于在主线程处理数据更新。我们称之为DataHandler。 ```cpp class DataHandler : public QObject { Q_OBJECT public slots: void handleData(const QString& data) { // 在此处更新TabView数据 // 您可以使用信号和槽机制将数据传递给TabView并进行更新 } }; ``` 2. 在主线程创建一个DataHandler对象,并将其与TabView连接起来。 ```cpp DataHandler dataHandler; QTabView tabView; QObject::connect(&dataHandler, SIGNAL(dataUpdated(QString)), &tabView, SLOT(updateData(QString))); ``` 在此示例,我们假设TabView具有名为updateData的槽函数,用于接收并更新数据。 3. 在子线程执行耗时操作,并在完成后将数据发送到DataHandler。 ```cpp void MyThread::run() { // 执行耗时操作 QString data = performLongOperation(); // 发送数据到主线程的DataHandler QMetaObject::invokeMethod(&dataHandler, "handleData", Qt::QueuedConnection, Q_ARG(QString, data)); } ``` 在此示例,我们假设在子线程执行了一个名为performLongOperation的耗时操作,并将结果存储在data变量。然后,我们使用QMetaObject::invokeMethod将数据传递给DataHandler对象的handleData槽函数。 请注意,使用Qt的信号和槽机制,您可以在主线程安全地更新UI元素,而无需直接在子线程操作UI。 希望这可以帮助到您!如果您有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白技术栈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值