Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说QTableView详细使用说明,希望能够帮助你!!!。
QTableView是一种View/Model
模式在创建QTableView表格的时,除了创建QTableView对象还需要创建对应的Model对象,Model对象负责表格中的数据单元添加、单元格删除和设置表格标题等操作,一般常见的就是QStandardItemModel
模型。
使用时需要包含#include <QTableView>
和#include <QStandardItemModel>
,创建一个QTableView
对象和QStandardItemModel
并使用QTableView
的setModel()
函数将视图和模型对象进行绑定。下面以继承QTableView
为示例,代码如下所示:
// .h
#include <QTableView>
#include <QStandardItemModel>
class DBTableView
: public QTableView
{
public:
explicit DBTableView(QWidget * _parent_widget = nullptr);
~DBTableView() override;
private:
QStandardItemModel* db_table_model_;
};
// .cpp
#include "db_table_view.h"
DBTableView::DBTableView(QWidget *_parent_widget)
: QTableView(_parent_widget)
{
db_table_model_ = new QStandardItemModel();
setModel(db_table_model_);
}
DBTableView::~DBTableView()
{
}
表格最重要的就是标题对于一个表格控件而言标题分为水平标题
和垂直标题
,可以使用model
对象提供的setHorizontalHeaderLabels()
函数和setVerticalHeaderLabels()
函数进行表格标题的设置,前者是对水平标题
的设置而后者是对垂直标题
的设置,示例代码和效果如下所示:
DBTableView::DBTableView(QWidget *_parent_widget)
: QTableView(_parent_widget)
{
// ......
QStringList table_h_headers;
table_h_headers << "设施ID" << "设施名称" << "设施等级" << "人员配置"<< "数据采集日期";
db_table_model_->setHorizontalHeaderLabels(table_h_headers);
QStringList table_v_headers;
table_v_headers << "测试1" << "测试2" << "测试3" << "测试4"<< "测试5";
db_table_model_->setVerticalHeaderLabels(table_v_headers);
}
表格控件上的所有单元格都是item
对象表格标题也不例外,因此可以单独创建item
对象然后通过model
的setHorizontalHeaderItem()
函数和setVerticalHeaderItem()
函数依次对表格进行的标题进行设置,示例代码如下:
DBTableView::DBTableView(QWidget *_parent_widget)
: QTableView(_parent_widget)
{
// ......
QStringList table_h_headers;
table_h_headers << "设施ID" << "设施名称" << "设施等级" << "人员配置"<< "数据采集日期";
for (int index = 0; index < table_h_headers.count(); ++index) {
QStandardItem * header_item = new QStandardItem(table_h_headers[index]);
db_table_model_->setHorizontalHeaderItem(index, header_item);
}
}
这种做法适用于对表格标题需要添加一些数据的时候,例如,当前的模型描述的数据库中的数据表,标题的显示文字可以写成中文,然后将其对应的数据库字段作为附加信息通过setData()
函数写道对象中,示例代码如下:
#include "db_table_view.h"
#define DATABASE_FIELD_CODE Qt::UserRole + 100
DBTableView::DBTableView(QWidget *_parent_widget)
: QTableView(_parent_widget)
{
// ......
QStringList table_h_headers;
table_h_headers << "设施ID" << "设施名称" << "设施等级" << "人员配置"<< "数据采集日期";
QStringList table_h_fields;
table_h_fields << "id" << "name" << "level" << "config"<< "date";
for (int index = 0; index < table_h_headers.count(); ++index) {
QStandardItem * header_item = new QStandardItem(table_h_headers[index]);
header_item->setData(table_h_fields[index], DATABASE_FIELD_CODE);
db_table_model_->setHorizontalHeaderItem(index, header_item);
}
}
设置表格标题后就是获取标题内容,可以通过model
的columnCount()
函数获取数量,配合model
的headerData()
函数获取当前列的文字内容,示例代码如下:
DBTableView::DBTableView(QWidget *_parent_widget)
: QTableView(_parent_widget)
{
// ......
QStringList table_h_headers;
table_h_headers << "设施ID" << "设施名称" << "设施等级" << "人员配置"<< "数据采集日期";
db_table_model_->setHorizontalHeaderLabels(table_h_headers);
for (int index = 0; index < db_table_model_->columnCount(); ++index) {
qInfo() << db_table_model_->headerData(index, Qt::Horizontal, Qt::DisplayRole).toString();
}
}
headerData()
的第一个参数是列的索引号,第二个参数是获取水平方向还是垂直方向的表头,第三个参数是模型数据编号,该编号与setData()
函数在设置时的一致,而这里使用的Qt::DisplayRole
是内置的一个编号,用于获取显示的文字内容。
设置好标题后就可以对表格进行添加数据了,可以使用model
的setItem()
函数和appendRow()
函数,其中setItem()
函数需要指定设置的行和列,而appendRow()
函数可以先将一行item
的对象添加一个list中然后一次性插入,示例代码如下:
DBTableView::DBTableView(QWidget *_parent_widget)
: QTableView(_parent_widget)
{
// ......
db_table_model_->setItem(0, 0, new QStandardItem("1"));
db_table_model_->setItem(0, 1, new QStandardItem("2"));
db_table_model_->setItem(0, 2, new QStandardItem("3"));
db_table_model_->setItem(0, 3,new QStandardItem("4"));
db_table_model_->setItem(0, 4,new QStandardItem("5"));
QList<QStandardItem*> add_items;
for (int index = 0; index < table_h_headers.count(); ++index) {
add_items << new QStandardItem(QString::number(index));
}
db_table_model_->appendRow(add_items);
}
删除数据时同样也是依赖model
对象,model
对象提供了一个clear()
函数,该函数可以一次将表格内容和表格标题都删掉,如果只是想将表格内容清空则可以使用model
的rowCount()
函数配合model
的removeRows()
函数完成,示例代码如下:
DBTableView::DBTableView(QWidget *_parent_widget)
: QTableView(_parent_widget)
{
// ......
db_table_model_->removeRows(0, db_table_model_->rowCount());
}
删除某一列数据可以使用model
的removeColumn()
函数,示例如下:
DBTableView::DBTableView(QWidget *_parent_widget)
: QTableView(_parent_widget)
{
// ......
db_table_model_->removeColumn(0);
}
对于表格而言可以对其样式进行调整,常见的设置如下:
horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
verticalHeader()->setDefaultAlignment(Qt::AlignBottom);
// 固定表格宽度不可扩展,不可手动调整宽度
horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
// 表格宽度随内容自动扩展
horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
// 表格宽度自动根据UI进行计算,不可手动调整宽度
horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
// 固定表格高度不可扩展,不可手动调整高度
verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
// 表格高度随内容自动扩展
verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
// 表格高度自动根据UI进行计算,不可手动调整高度
verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
// 隐藏网格线
setShowGrid(false);
// 显示网格线
setShowGrid(true);
// 线的样式
setGridStyle(Qt::DotLine);
对于表格控件常见的操作就是弹出菜单,当鼠标点击控件时会触发一个QEvent::ContextMenu
类型的事件,通过重载eventFilter()
事件过滤器函数,并捕获该类型事件来实现菜单的弹出,具体步骤如下:
// .h
// ......
#include <QEvent>
#include <QMenu>
class DBTableView
: public QTableView
{
Q_OBJECT
// ......
protected:
bool eventFilter(QObject *object, QEvent *event) override;
};
// .cpp
DBTableView::DBTableView(QWidget *_parent_widget)
: QTableView(_parent_widget)
{
// ......
installEventFilter(this);
}
bool DBTableView::eventFilter(QObject *object, QEvent *event) {
if(object == this && event->type() == QEvent::ContextMenu) {
if(currentIndex().isValid()) {
QMenu * menu = new QMenu();
menu->addAction("添加数据");
menu->addAction("删除数据");
QAction * action = menu->exec(cursor().pos()); // 弹出菜单
if (action->text().compare("删除数据") == 0) {
db_table_model_->removeRow(currentIndex().row());
}
}
}
return QAbstractItemView::eventFilter(object, event);
}
效果如下:
除了直接监听eventFilter
之外还有一个简单一些的方式调用QTableView的setContextMenuPolicy()
函数,示例代码如下:
void TestTable::initUI() {
QTableView * table_view = new QTableView();
table_view->setContextMenuPolicy(Qt::CustomContextMenu);
}
在创建完QTableView对象后设置使用自定义菜单策略,然后进行信号槽关联,示例代码如下:
void TestTable::tableViewMenu(const QPoint & _pos) {
// 相应数据处理
}
void TestTable::initUI() {
// ......
connect(table_view, &QTableView::customContextMenuRequested, this, &TestTabel::tableViewMenu);
}
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
上一篇
已是最后文章
下一篇
已是最新文章