展示线程内数据:
QQueue<QString> queJg; //推送结果 QMutex queJg_; QTimer* tmrTable = new QTimer();//表格数据时钟
//线程内插入数据 queJg_.lock(); queJg.append(url + "|" + ls[2] + "|" + tjid + "|" + ad); queJg_.unlock();
//表格数据时钟 connect(tmrTable, &QTimer::timeout, this, &jjsoft::tmrTableTimeout); tmrWork->start(1000); //显示表格数据 void jjsoft::tmrTableTimeout() { //首先去除队列中的推送结果 QStringList tmpLs; queJg_.lock(); while (!queJg.isEmpty()) { tmpLs.append(queJg.dequeue()); } queJg_.unlock(); //显示到表格中 if (tmpLs.count() > 0) { int iGe = 0; for (int i = 0; i < tmpLs.count(); i++) { QString one = tmpLs[i]; auto arr = one.split("|"); if (arr.count() != 2) { continue; } QList<QStandardItem*> list; list << new QStandardItem(arr[0]) << new QStandardItem(arr[1]); model->insertRow(0, list); //在第0行插入一条记录 model->removeRow(100); qApp->processEvents(); iGe++; if (iGe > 1000) { break; } } } }
数据模型:
QStandardItemModel* model;//表模型 //设置表头 model = new QStandardItemModel(this); QStringList tabHead; tabHead << "设施ID" << "设施名称" << "设施等级" << "人员配置" << "数据采集日期"; model->setHorizontalHeaderLabels(tabHead); ui.tab_tj->setModel(model);
设置一条数据:
/*设置一条数据*/ model->setItem(0, 0, new QStandardItem("张三")); model->setItem(0, 1, new QStandardItem("3")); model->setItem(0, 2, new QStandardItem("男"));
设置行标头,和列标头
/*设置列字段名*/ model->setColumnCount(3); model->setHeaderData(0,Qt::Horizontal, "姓名"); model->setHeaderData(1,Qt::Horizontal, "年龄"); model->setHeaderData(2,Qt::Horizontal, "性别"); /*设置行字段名*/ model->setRowCount(3); model->setHeaderData(0,Qt::Vertical, "记录一"); model->setHeaderData(1,Qt::Vertical, "记录二"); model->setHeaderData(2,Qt::Vertical, "记录三");
3 移除数据
model->removeRow(0);//移除第0行数据 model->removeColumn(0);//移除第0列数据
4 插入数据
QList<QStandardItem*> list; list << new QStandardItem("王五") << new QStandardItem("22") << new QStandardItem("男"); model->insertRow(0, list); //在第0行插入一条记录
5 数据变更信号处理
public slots: void dataChangedSlot(const QModelIndex &topLeft, const QModelIndex &bottomRight,const QVector<int> &roles = QVector<int> ()); void Widget::dataChangedSlot(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) { qDebug() << model->data(topLeft).toString() << endl; } //链接信号 connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), this, SLOT(dataChangedSlot(QModelIndex,QModelIndex,QVector<int>)));
6 常用函数
//默认显示行头,如果你觉得不美观的话,我们可以将隐藏 tableview->verticalHeader()->hide(); //设置选中时为整行选中 tableview->setSelectionBehavior(QAbstractItemView::SelectRows); //设置表格的单元为只读属性,即不能编辑 tableview->setEditTriggers(QAbstractItemView::NoEditTriggers); //返回一个被选中的所有Item的索引,一般是去遍历这个链表进行处理[virtual protected] QModelIndexList QTableView::selectedIndexes() const
7 QStandardItem被点选信号
void QAbstractItemView::clicked(const QModelIndex &index);/**返回被点选的Item的索引*/
8 QItemDelegate代理
QTableView在处理信息显示编辑的时候比较单调,类似行编辑器,为了获得更多的灵性性,交互通过QItemDelegate执行。
下面通过派生一个SpinDelegate来实现一个整数旋转框的代理器。
一般我们要重写函数createEditor:
[virtual] QWidget *QItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const /**QWidget *parent一般是指哪个窗口使用了这个代理,一般用来托管内存 * QStyleOptionViewItem &option 样式风格 * const QModelIndex &index 需要更改的Item索引*/
void dataChangedSlot(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int> ()); void Widget::dataChangedSlot(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) { qDebug() << model->data(topLeft).toString() << endl; } //设置代理 ui.tab_tj->setItemDelegate(new SpinDelegate(this)); connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),this,SLOT(dataChangedSlot(QModelIndex,QModelIndex,QVector<int>)));
spinDelegate.h
#ifndef SPINDELEGATE_H#define SPINDELEGATE_H#include <QItemDelegate>class SpinDelegate : public QItemDelegate {public: SpinDelegate(QObject *parent = Q_NULLPTR); QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; };#endif // SPINDELEGATE_H
spinDelegate.cpp
#include "spindelegate.h"#include <QSpinBox>SpinDelegate::SpinDelegate(QObject *parent): QItemDelegate(parent) { } QWidget* SpinDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const{ if(index.column() == 1) // 返回下拉框 { QSpinBox* box = new QSpinBox(parent); box->setMinimum(1); box->setMaximum(99); return box; } return QItemDelegate::createEditor(parent, option, index); }
QTableView 列宽设置解释
1、列宽设置如下:
view->setColumnWidth(1, 100);//设置第1列宽100 view->resizeColumnToContents(1);//设置第1列宽度自适应内容 view->resizeColumnsToContents();//设置所有列宽度自适应内容 //下面是通过表头设置列宽 view->horizontalHeader()->setMinimumSectionSize(100);//设置最小列宽 view->horizontalHeader()->setMaximumSectionSize(100);//设置最大列宽 //设置第1列自动... temptb->horizontalHeader()->setSectionResizeMode(2,QHeaderView::Stretch); //设置所有列自动... temptb->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); /*第二个参数可以为: QHeaderView::Interactive :0 用户可设置,也可被程序设置成默认大小 QHeaderView::Fixed :2 用户不可更改列宽 QHeaderView::Stretch :1 根据空间,自动改变列宽,用户与程序不能改变列宽 QHeaderView::ResizeToContents:3 根据内容改变列宽,用户与程序不能改变列宽 */
2、注意事项:
(1)设置固定的列宽要在view->seModel(model);之后进行设置,不然无效;
(2)通过表头设置setSectionResizeMode时,参数为QHeaderView::Stretch 和 QHeaderView::ResizeToContents 时,用户和程序不能改变列宽;因此,当内容太多时,用QHeaderView::Stretch时这些内容可能不会完全显示,用户因为不能改变列宽而不能拖动查看隐藏部分;用QHeaderView::ResizeToContents时,内容太多的这一列会特别长;注意效果!
(3)除了(2)中的两种情况,其他时,用户均能改变列宽;
(4)所以,如果知道每列内容长度不会很长,可以用QHeaderView::Stretch, QHeaderView::ResizeToContents,
(5)如果无法预料内容长度,还是设置固定宽度为好。
(6)view->resizeColumnToContents(1);view->resizeColumnsToContents();必须在model里加入内容后执行列宽才能适应内容宽度;否则model为空时执行此句,列宽只能适应空内容而变的很窄,之后再添加内容也不会变宽;