导言:记录一下Qt使用 std::thread 线程插入数据到 QTableWidget中
QThread 使用的时候有时候不太方便,所有使用c++标准库里面的thread。
我的需求就是使用一个线程去更新 QTableWidget 里面的数据。因为我的界面主线程总是比这个子线程晚结束。我就采用的 detach ,把这个更新数据的线程分离出去。在整个应用使用的是不安全的单例来作为线程执行函数。
在线程中通过发射 updateProductInfo 信号,让GUI主界面线程去响应这个信号去更新表格的内容。
Qt使用thread线程插入数据到QTableWidget
#ifndef THREADTABLE_H
#define THREADTABLE_H
#include
#include
#include
namespace Ui {
class ThreadTable;
}
class ThreadTable : public QWidget
{
Q_OBJECT
public:
//单例
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
#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();
}
#include
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//不要直接用构造函数,不然会有多个实例在内容里面,有时候就设置不对劲了
ThreadTable * w = ThreadTable::GetInstance();
w->show();
return a.exec();
}
//线程执行函数
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);
}
}
//注册的一些例子
qRegisterMetaType<QTextBlock>("QTextBlock");
qRegisterMetaType<QTextDocument*>("QTextDocument*");
qRegisterMetaType<QList<QList<double>>>("QList>" );
//按钮启动去更新页面
void ThreadTable::on_pushButton_clicked()
{
//在这里加都可以的,在构造函数加最好啦
//qRegisterMetaType<数据类型>("数据类型"); 这个尖括号和圆括号里面的字符串要一致哈,不然会出问题
std::thread m_thread(&ThreadTable::GetInstance()->upDateTable);
//线程要分离,不然会卡顿
m_thread.detach();
}