cpp
#pragma once
#include <QAbstractTableModel>
#include <QVariant>
class MyTableModel :public QAbstractTableModel {
Q_OBJECT
public:
MyTableModel(QObject* parent = nullptr):QAbstractTableModel(parent){}
int rowCount(const QModelIndex &parent = QModelIndex()) const override {
return 5;
}
int columnCount(const QModelIndex &parent = QModelIndex()) const override {
return 3;
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {
if (!index.isValid() || role != Qt::DisplayRole) {
return QVariant();
}
return index.row() + index.column();
}
};
cpp
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_QtWidgetsApplication1.h"
#include <QStandardItemModel>
#include <QItemSelectionModel>
#include "MyTableModel.hpp"
class QtWidgetsApplication1 : public QMainWindow
{
Q_OBJECT
public:
QtWidgetsApplication1(QWidget *parent = nullptr);
~QtWidgetsApplication1();
MyTableModel myModel;
private:
Ui::QtWidgetsApplication1Class ui;
};
cpp
#include "QtWidgetsApplication1.h"
QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
//为UI设置模型
ui.tableView->setModel(&myModel);
}
QtWidgetsApplication1::~QtWidgetsApplication1()
{}
表格样式:
Qt模型中的role是用来在数据项(通常是表格模型中的单元格)上标识不同的数据信息的。每个数据项可以有多个role,每个role代表不同的数据信息,例如显示的文本、图标、背景色等。
在Qt中,通过Qt::ItemDataRole
枚举定义了不同的预定义角色:
enum ItemDataRole {
DisplayRole = 0, // 显示的文本
DecorationRole, // 用于装饰数据的,例如图标
EditRole, // 可编辑的数据
ToolTipRole, // 工具提示
StatusTipRole, // 状态提示
WhatsThisRole, // "What's This?" 帮助信息
SizeHintRole, // 数据项的大小提示
FontRole, // 字体信息
TextAlignmentRole, // 文本对齐方式
BackgroundColorRole, // 背景色
// ... 等等
};
自定义角色时,可以使用Qt::UserRole + 1
开始扩展。
例如,下面的代码演示了如何在自定义的表格模型中实现不同的role:
QVariant MyTableModel::data(const QModelIndex &index, int role) const {
if (!index.isValid())
return QVariant();
if (role == Qt::TextColorRole) {
// 返回文字颜色
return QColor(Qt::red);
} else if (role == Qt::DisplayRole) {
// 返回显示的文本
return "显示文本";
} else if (role == Qt::DecorationRole) {
// 返回装饰用的图标
return QIcon("path_to_icon");
}
// ... 其他角色的处理
return QVariant();
}
Qt::ItemFlags MyTableModel::flags(const QModelIndex &index) const {
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
if (index.isValid()) {
// 设置可编辑
flags |= Qt::ItemIsEditable;
// 设置可以设置背景色
flags |= Qt::ItemNeverHasAttributes;
}
return flags;
}
在这个例子中,我们定义了两个role:Qt::TextColorRole
和Qt::DisplayRole
,并且在flags
函数中设置了这些role是可以被应用的。在实际的数据获取函数data
中,我们根据传入的role值来返回不同的数据。
cpp
QVariant MyTableModel::data(const QModelIndex &index, int role) const override {
if (!index.isValid())
return QVariant();
if (role == Qt::DisplayRole) {
// 返回用于显示的数据
return QString("行 %1, 列 %2").arg(index.row() + 1).arg(index.column() + 1);
}
else if (role == Qt::FontRole) {
QFont font;
font.setBold(true);
return font;
}
else if (role == Qt::BackgroundRole) {
return QBrush(Qt::lightGray);
}
return QVariant();
}
交互和编辑功能:
cpp
//通过实现模型的 setData() 方法来响应数据的更改。
bool MyTableModel::setData(const QModelIndex &index, const QVariant &value, int role) {
if (index.isValid() && role == Qt::EditRole)
return true;
return false;
}
//为了启用编辑功能,还需要在模型中实现 flags() 方法,并返回合适的标志。
Qt::ItemFlags MyTableModel::flags(const QModelIndex &index) const {
if (!index.isValid())
return Qt::ItemIsEnabled;
return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
}
完整示例:
cpp
#pragma once
#include <QAbstractTableModel>
#include <QVariant>
#include <QFont>
#include <QBrush>
#include <QList>
#include <QPair>
class MyTableModel :public QAbstractTableModel {
Q_OBJECT
public:
MyTableModel(QObject* parent = nullptr):QAbstractTableModel(parent){
employees << QPair<QString, QString>("Alice", "HR")
<< QPair<QString, QString>("Bob", "IT")
<< QPair<QString, QString>("Carol", "Finance");
}
int rowCount(const QModelIndex &parent = QModelIndex()) const override {
return employees.count();
}
int columnCount(const QModelIndex &parent = QModelIndex()) const override {
return 2;
}
QVariant MyTableModel::data(const QModelIndex &index, int role) const override {
if (!index.isValid() || role != Qt::DisplayRole)
return QVariant();
const auto &employee = employees[index.row()];
if (index.column() == 0) return employee.first;
if (index.column() == 1) return employee.second;
return QVariant();
}
//通过实现模型的 setData() 方法来响应数据的更改。
bool MyTableModel::setData(const QModelIndex &index, const QVariant &value, int role) {
if (index.isValid() && role == Qt::EditRole)
return true;
return false;
}
//为了启用编辑功能,还需要在模型中实现 flags() 方法,并返回合适的标志。
Qt::ItemFlags MyTableModel::flags(const QModelIndex &index) const {
if (!index.isValid())
return Qt::ItemIsEnabled;
return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
}
private:
QList<QPair<QString, QString>> employees;
};
cpp
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_QtWidgetsApplication1.h"
#include <QStandardItemModel>
#include <QItemSelectionModel>
#include "MyTableModel.hpp"
#include <QSortFilterProxyModel>
class QtWidgetsApplication1 : public QMainWindow
{
Q_OBJECT
public:
QtWidgetsApplication1(QWidget *parent = nullptr);
~QtWidgetsApplication1();
MyTableModel myModel;
QSortFilterProxyModel proxyModel;
private:
Ui::QtWidgetsApplication1Class ui;
};
cpp
#include "QtWidgetsApplication1.h"
QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
//设置源模型
proxyModel.setSourceModel(&myModel);
//为UI设置模型
ui.tableView->setModel(&proxyModel);
//启用排序
ui.tableView->setSortingEnabled(true);
}
QtWidgetsApplication1::~QtWidgetsApplication1()
{}