> 文章列表 > Qt使用 std::thread 线程插入数据到 QTableWidget

Qt使用 std::thread 线程插入数据到 QTableWidget

Qt使用 std::thread 线程插入数据到 QTableWidget

Qt使用 std::thread 线程插入数据到 QTableWidget中

  • 一、实现效果
  • 二、主要代码
    • 1. ThreadTable.h 头文件
    • 2. ThreadTable.cpp 源文件
    • 3. 主函数
  • 三、注意要点

导言:记录一下Qt使用 std::thread 线程插入数据到 QTableWidget中

QThread 使用的时候有时候不太方便,所有使用c++标准库里面的thread。

我的需求就是使用一个线程去更新 QTableWidget 里面的数据。因为我的界面主线程总是比这个子线程晚结束。我就采用的 detach ,把这个更新数据的线程分离出去。在整个应用使用的是不安全的单例来作为线程执行函数。

在线程中通过发射 updateProductInfo 信号,让GUI主界面线程去响应这个信号去更新表格的内容。

一、实现效果

Qt使用thread线程插入数据到QTableWidget

二、主要代码

1. ThreadTable.h 头文件

#ifndef THREADTABLE_H
#define THREADTABLE_H#include <QWidget>
#include <thread>
#include <QObject>namespace Ui {
class ThreadTable;
}class ThreadTable : public QWidget
{Q_OBJECTpublic://单例static ThreadTable * GetInstance();private:Ui::ThreadTable *ui;QList<QList<QString>> productTable;explicit ThreadTable(QWidget *parent = nullptr);~ThreadTable();static ThreadTable * Instance;//更新表格的函数static void upDateTable();
Q_SIGNALS://更新数据的信号void updateProductInfo(int row, int column, QString data);private Q_SLOTS://UI界面响应插入信号void SlotUpdateProductInfo(int row, int column, QString data);//启动线程按钮void on_pushButton_clicked();
};#endif // THREADTABLE_H

2. ThreadTable.cpp 源文件

#include "ThreadTable.h"
#include "ui_ThreadTable.h"
ThreadTable* ThreadTable::Instance = nullptr;
ThreadTable::ThreadTable(QWidget *parent) :QWidget(parent),ui(new Ui::ThreadTable)
{ui->setupUi(this);//表格的一些更新ui->productTB->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);ui->productTB->setRowCount(20);ui->productTB->setColumnCount(5);//关联槽函数connect(this, &ThreadTable::updateProductInfo, this, &ThreadTable::SlotUpdateProductInfo);//初始化数据productTable = {{"1", "牙刷","2022-11-13", "2023-1-3", "成都智康科技有限公司"},{"2", "牙膏","2022-3-5", "2023-1-3", "成都科技有限公司"},{"3", "牛皮","2022-4-7", "2023-1-3", "成都康科技有限公司"},{"4", "纸币","2022-5-13", "2023-1-3", "成都智科技有限公司"},{"5", "皮鞋","2022-11-13", "2023-1-3", "成都智康科技有限公司"},{"6", "核酸","2022-3-5", "2023-1-3", "成都科技有限公司"},{"7", "漱口水","2022-4-7", "2023-1-3", "成都康科技有限公司"},{"8", "可乐","2022-5-13", "2023-1-3", "成都智科技有限公司"},{"9", "牙刷","2022-11-13", "2023-1-3", "成都智康科技有限公司"},{"10", "牙膏","2022-3-5", "2023-1-3", "成都科技有限公司"},{"11", "牛皮","2022-4-7", "2023-1-3", "成都康科技有限公司"},{"12", "纸币","2022-5-13", "2023-1-3", "成都智科技有限公司"},{"13", "皮鞋","2022-11-13", "2023-1-3", "成都智康科技有限公司"},{"14", "核酸","2022-3-5", "2023-1-3", "成都科技有限公司"},{"15", "漱口水","2022-4-7", "2023-1-3", "成都康科技有限公司"},{"16", "可乐","2022-5-13", "2023-1-3", "成都智科技有限公司"}};}ThreadTable::~ThreadTable()
{delete ui;
}ThreadTable *ThreadTable::GetInstance()
{if(Instance == nullptr){Instance = new ThreadTable;}return Instance;
}void ThreadTable::upDateTable()
{for (int i = 0; i < ThreadTable::GetInstance()->productTable.length(); i++){for (int j = 0; j < 5; j++){emit ThreadTable::GetInstance()->updateProductInfo(i, j, ThreadTable::GetInstance()->productTable[i][j]);}//一行就延时 1s_sleep(1000);}
}void ThreadTable::SlotUpdateProductInfo(int row, int column, QString data)
{ui->productTB->setItem(row, column, new QTableWidgetItem(data));
}void ThreadTable::on_pushButton_clicked()
{std::thread m_thread(&ThreadTable::GetInstance()->upDateTable);//线程要分离,不然会卡顿m_thread.detach();
}

3. 主函数

#include <QApplication>
#include <ThreadTable.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);//不要直接用构造函数,不然会有多个实例在内容里面,有时候就设置不对劲了ThreadTable * w = ThreadTable::GetInstance();w->show();return a.exec();
}

三、注意要点

  • 因为我们不能在线程去设置主线程的一些ui,我们必须通过在 线程里面去发送更新数据的信号,用信号去传数据, 用信号槽去更新界面
//线程执行函数
void ThreadTable::upDateTable()
{for (int i = 0; i < ThreadTable::GetInstance()->productTable.length(); i++){for (int j = 0; j < 5; j++){emit ThreadTable::GetInstance()->updateProductInfo(i, j, ThreadTable::GetInstance()->productTable[i][j]);}//一行就延时 1s_sleep(1000);}
}
  • 有时候我们传递的信号 用了一些特殊的数据结构或者类,我们必须在线程启动前,在Qt里面注册这个数据类型
//注册的一些例子
qRegisterMetaType<QTextBlock>("QTextBlock");
qRegisterMetaType<QTextDocument*>("QTextDocument*");
qRegisterMetaType<QList<QList<double>>>("QList<QList<double>>");//按钮启动去更新页面
void ThreadTable::on_pushButton_clicked()
{//在这里加都可以的,在构造函数加最好啦//qRegisterMetaType<数据类型>("数据类型"); 这个尖括号和圆括号里面的字符串要一致哈,不然会出问题std::thread m_thread(&ThreadTable::GetInstance()->upDateTable);//线程要分离,不然会卡顿m_thread.detach();
}