前言
这篇主要来聊下qt中数据列表的使用,绑定等,当然也都是些比较基础的,不存在什么花里胡哨的东西。
数据列表
qt中有单列的QListView、QListWidget,有表格QTableView、QTableWidget,有树状菜单QTreeView、QTreeWidget,具体的区别就是,View基于Model(玩过MVC的应该清楚视图与模型的绑定),Widget直接基于Item,Widget集成View,内部已经实现了默认的Model,通过方法addItem直接可以添加数据,我们主要来看下View的使用,毕竟这种便于数据维护。
QListView
列表视图一般用在一些像切换界面,菜单选择等的单列式数据展示,对应的Model为QStringListModel,当然也可以用更高级的QStandardItemModel,先来看下简单的实现效果。
数据绑定
1 2 3 4 5
| #include <QStringListModel> ... private: QStringListModel* m_listModel;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| void TestWidget::init() { m_listModel = new QStringListModel();
setConnection(); bindList(); }
void TestWidget::bindList() { QStringList list; list.append(QStringLiteral("龙门石窟")); list.append(QStringLiteral("白马寺")); list.append(QStringLiteral("关林庙")); m_listModel->setStringList(list);
ui->listView->setModel(m_listModel); ui->listView->setSpacing(5); QModelIndex index = m_listModel->index(0); ui->listView->setCurrentIndex(index); }
|
事件绑定
常规的使用,这里只演示下双击事件,其他事件查看QListView的事件机制对应搞就行了,做双击的时候记得先禁用修改事件,默认是双击可以切换成LineEdit做修改。
1 2
| ui->listView->setEditTriggers(QAbstractItemView::EditTrigger::NoEditTriggers);
|
1 2 3 4 5 6 7 8 9 10
| void TestWidget::listViewDoubleClicked(const QModelIndex& index) { std::cout << "clicked index : " << index.row() << std::endl; }
void TestWidget::setConnection() { connect(ui->listView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(listViewDoubleClicked(const QModelIndex&))); }
|
右键菜单
通过以下方式打开ListView的右键菜单,然后再创建个菜单绑定到ListView中,当然同时也可以绑定QMenu对应Action的事件来做进一步的使用,这个后面用到再进行示例的演示。
1 2
| ui->listView->setContextMenuPolicy(Qt::CustomContextMenu);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void TestWidget::init() { m_listMenu = new QMenu(ui->listView); m_listMenu->addAction("test1"); m_listMenu->addAction("test2"); }
void TestWidget::listContextMenuShow(const QPoint& pos) { m_listMenu->exec(ui->listView->mapToGlobal(pos)); }
void TestWidget::setConnection() { connect(ui->listView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(listViewDoubleClicked(const QModelIndex&))); connect(ui->listView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(listContextMenuShow(const QPoint&))); }
|

QTableView
表格视图在一些与数据打交道的应用上尤为常见,根据不同的数据做对应的列展示,数据绑定等比较方便,一般对应的Model为QStandardItemModel。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include <QStandardItemModel> #include <vector>
struct TestItem { int id; QString name; int age; short sex; QString location; };
private: QStandardItemModel* m_tableModel; std::vector<TestItem> m_data;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| void TestWidget::bindTable() { QStringList header; header << "id" << QStringLiteral("姓名") << QStringLiteral("性别") << QStringLiteral("年龄") << QStringLiteral("地址"); m_tableModel->setHorizontalHeaderLabels(header);
for (int i = 0; i < m_data.size(); i++) { m_tableModel->setItem(i, 0, new QStandardItem(QString::number(m_data[i].id))); m_tableModel->setItem(i, 1, new QStandardItem(m_data[i].name)); m_tableModel->setItem(i, 2, new QStandardItem(m_data[i].sex == 1 ? QStringLiteral("男") : QStringLiteral("女"))); m_tableModel->setItem(i, 3, new QStandardItem(QString::number(m_data[i].age))); m_tableModel->setItem(i, 4, new QStandardItem(m_data[i].location));
for (int j = 0; j < 5; j++) { m_tableModel->item(i, j)->setTextAlignment(Qt::AlignCenter); } }
ui->tableView->setModel(m_tableModel);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows); ui->tableView->setShowGrid(false); ui->tableView->setAlternatingRowColors(true); ui->tableView->verticalHeader()->hide(); ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); ui->tableView->verticalHeader()->setDefaultSectionSize(40); ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); }
void TestWidget::initData() { for (int i = 0; i < 10; i++) { TestItem item; item.id = i + 1; item.name = QString("test%1").arg(i + 1); item.sex = i % 2 == 0 ? 1 : 2; item.age = (i + 1) * 5; item.location = QStringLiteral("大洛阳"); m_data.push_back(item); } }
|
至于事件、右键菜单同QListView,这里就不再多说了,看下效果。

QTreeView
树状列表一般像组织架构、系统菜单、角色权限设置、目录结构等会比较常用,个人使用这个确实不多,大致看下用法吧。
1 2
| QStandardItemModel* m_treeModel;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| void TestWidget::bindTree() { for (int i = 0; i < 5; i++) { QStandardItem* item = new QStandardItem(QString("item %1").arg(i));
item->setCheckable(true); if (i % 2 == 0) { for (int j = 0; j < 3; j++) { QStandardItem* childItem = new QStandardItem(QString("child item %1").arg(j)); childItem->setCheckable(true); item->appendRow(childItem); } } m_treeModel->setItem(i, item); } ui->treeView->setModel(m_treeModel); ui->treeView->setHeaderHidden(true); }
|
可以看到,实质上QStandardItem本身已经支持树型结构,通过appendRow来添加子节点。
其他的像点击啊右键菜单也是类似,至于选中态这种等后续鼓捣过实际用到再补充吧。

小结
数据展示目的就是为了查阅、维护、做数据分析,少不了后续涉及到增删改查,一个个来吧,鼓捣东西这条路走开了就停不下来了。