QTableView
阅读数:38 评论数:0
跳转到新版页面分类
C/C++
正文
一、概述
QTableView
是 Qt 中一个功能强大的表格显示控件,它依赖于模型-视图-委托(Model-View-Delegate)架构。QTableView
提供了灵活的数据展示和编辑功能,适用于复杂的数据表格展示需求。
二、基本使用步骤
1、创建并配置 QTableView
。
2、创建并配置数据模型(如 QStandardItemModel
)。
3、将数据模型设置为 QTableView
的模型。
4、(可选)自定义视图外观和行为。
示例
#include <QApplication>
#include <QTableView>
#include <QStandardItemModel>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// 创建 QTableView 实例
QTableView tableView;
tableView.setWindowTitle("QTableView Example");
// 创建模型
QStandardItemModel model(5, 3); // 5行3列
model.setHorizontalHeaderLabels({"Column 1", "Column 2", "Column 3"});
// 填充数据
for (int row = 0; row < 5; ++row) {
for (int col = 0; col < 3; ++col) {
QStandardItem *item = new QStandardItem(QString("Item %1,%2").arg(row).arg(col));
model.setItem(row, col, item);
}
}
// 将模型设置为 QTableView 的模型
tableView.setModel(&model);
// 显示 QTableView
tableView.show();
return app.exec();
}
三、自定义外观
1、设置列宽
tableView.setColumnWidth(0, 150); // 设置第一列宽度为150像素
2、设置选择模式
tableView.setSelectionMode(QAbstractItemView::SingleSelection); // 仅允许单选
tableView.setSelectionBehavior(QAbstractItemView::SelectRows); // 选择整行
tableWidget.setSelectionMode(QTableWidget::MultiSelection); // 多行选择
设置行选中的背景色和字体颜色
// 设置选中行的背景色和字体颜色
tableView.setStyleSheet("QTableView::item:selected { background-color: #3399FF; color: white; }");
3、隐藏网格线
tableView.setShowGrid(false);
4、设置排序功能
tableView.setSortingEnabled(true);
5、自定义委托
你可以自定义委托来控制单元格的显示和编辑行为。以下是一个简单的示例,使用 QStyledItemDelegate
来自定义单元格的显示:
class CustomDelegate : public QStyledItemDelegate {
public:
CustomDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override {
// 自定义绘制代码
painter->save();
painter->setPen(Qt::blue);
painter->drawText(option.rect, Qt::AlignCenter, index.data().toString());
painter->restore();
}
};
// 使用自定义委托
tableView.setItemDelegate(new CustomDelegate(&tableView));
6、隐藏行号(如果不需要默认的行号)
tableView.verticalHeader()->setVisible(false); // 隐藏默认行号
7、设置表头样式
tableView.setStyleSheet(
"QHeaderView::section {"
" background-color: #4CAF50;" // 表头背景色
" color: white;" // 表头字体颜色
" font-size: 14px;" // 表头字体大小
" font-weight: bold;" // 表头字体加粗
" height: 30px;" // 表头高度
" border: none;" // 表头去掉边框
"}"
"QTableView::item:selected {"
" background-color: #FF9800;" // 选中行背景色
" color: white;" // 选中行字体颜色
"}"
);
8、默认选中第一行
// 设置整行选择
tableView.setSelectionBehavior(QTableView::SelectRows);
// 设置单行选择模式
tableView.setSelectionMode(QTableView::SingleSelection);
// 默认选中第一行
QModelIndex firstIndex = model.index(0, 0); // 获取第一行的第一个单元格的索引
tableView.setCurrentIndex(firstIndex); // 设置当前选中的索引
tableView.selectRow(0);
四、QStandardItemModel
QStandardItemModel
是一种数据模型,用于存储和管理二维表格数据。与许多其他 Qt 对象不同,QStandardItemModel
的构造函数不需要指定父对象(parent
)。这是因为数据模型通常由视图(如 QTableView
、QTreeView
等)持有,而视图本身会负责管理模型的生命周期。
void loadModelFromFile(QStandardItemModel *model, const QString &fileName) {
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning("Cannot open file for reading");
return;
}
QTextStream in(&file);
bool isFirstLine = true;
while (!in.atEnd()) {
QString line = in.readLine();
QStringList fields = line.split(',');
if (isFirstLine) {
// 设置表头
model->setHorizontalHeaderLabels(fields);
isFirstLine = false;
} else {
// 添加数据行
QList<QStandardItem *> items;
for (const QString &field : fields) {
items.append(new QStandardItem(field.trimmed()));
}
model->appendRow(items);
}
}
file.close();
}
#include <QApplication>
#include <QTableView>
#include <QStandardItemModel>
#include <QFile>
#include <QTextStream>
#include <QDebug>
void saveModelToFile(QStandardItemModel *model, const QString &fileName) {
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qWarning("Cannot open file for writing");
return;
}
QTextStream out(&file);
// 写入表头
QStringList headerLabels;
for (int col = 0; col < model->columnCount(); ++col) {
headerLabels << model->headerData(col, Qt::Horizontal).toString();
}
out << headerLabels.join(",") << "\n";
// 写入数据行
for (int row = 0; row < model->rowCount(); ++row) {
QStringList rowValues;
for (int col = 0; col < model->columnCount(); ++col) {
QStandardItem *item = model->item(row, col);
if (item) {
rowValues << item->text();
} else {
rowValues << "";
}
}
out << rowValues.join(",") << "\n";
}
file.close();
}
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// 创建 QTableView 和 QStandardItemModel
QTableView tableView;
QStandardItemModel model(5, 3); // 5 行 3 列
// 填充一些示例数据
for (int row = 0; row < 5; ++row) {
for (int col = 0; col < 3; ++col) {
QStandardItem *item = new QStandardItem(QString("Item %1,%2").arg(row).arg(col));
model.setItem(row, col, item);
}
}
tableView.setModel(&model);
tableView.show();
// 保存模型数据到文件
QString fileName = "output.csv"; // 请替换为你的文件路径
saveModelToFile(&model, fileName);
return app.exec();
}
五、实现搜索功能
在 QTableView
中实现搜索功能可以通过过滤模型(如 QSortFilterProxyModel
)来实现。QSortFilterProxyModel
可以过滤和排序数据,并将结果显示在 QTableView
中。
#include <QApplication>
#include <QTableView>
#include <QStandardItemModel>
#include <QSortFilterProxyModel>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QWidget>
#include <QHeaderView>
class MainWindow : public QWidget {
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr) : QWidget(parent) {
QVBoxLayout *layout = new QVBoxLayout(this);
// 创建 QTableView 和 QStandardItemModel
QTableView *tableView = new QTableView(this);
QStandardItemModel *model = new QStandardItemModel(5, 4, this); // 5 行 4 列
// 填充一些示例数据
for (int row = 0; row < 5; ++row) {
for (int col = 0; col < 4; ++col) {
QStandardItem *item = new QStandardItem(QString("Item %1,%2").arg(row).arg(col));
model->setItem(row, col, item);
}
}
// 创建 QSortFilterProxyModel
QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(model);
proxyModel->setFilterKeyColumn(-1); // -1 表示所有列都进行过滤
tableView->setModel(proxyModel);
// 创建 QLineEdit 用于输入搜索关键字
QLineEdit *searchLineEdit = new QLineEdit(this);
searchLineEdit->setPlaceholderText("Search...");
// 连接 QLineEdit 的文本变化信号到过滤模型的过滤器
connect(searchLineEdit, &QLineEdit::textChanged, proxyModel, &QSortFilterProxyModel::setFilterWildcard);
layout->addWidget(searchLineEdit);
layout->addWidget(tableView);
setLayout(layout);
setWindowTitle("QTableView Search Example");
resize(600, 400);
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MainWindow mainWindow;
mainWindow.show();
return app.exec();
}
#include "main.moc"
六、最后一列为按钮列
#include <QStyledItemDelegate>
#include <QApplication>
#include <QMouseEvent>
#include <QPainter>
class MultiButtonDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
MultiButtonDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override {
if (index.column() == index.model()->columnCount() - 1) {
int buttonWidth = option.rect.width() / 3;
QStyleOptionButton buttonOption1;
buttonOption1.rect = option.rect.adjusted(0, 0, -2 * buttonWidth, 0);
buttonOption1.text = "Button 1";
buttonOption1.state = QStyle::State_Enabled;
QStyleOptionButton buttonOption2;
buttonOption2.rect = option.rect.adjusted(buttonWidth, 0, -buttonWidth, 0);
buttonOption2.text = "Button 2";
buttonOption2.state = QStyle::State_Enabled;
QStyleOptionButton buttonOption3;
buttonOption3.rect = option.rect.adjusted(2 * buttonWidth, 0, 0, 0);
buttonOption3.text = "Button 3";
buttonOption3.state = QStyle::State_Enabled;
QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption1, painter);
QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption2, painter);
QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption3, painter);
} else {
QStyledItemDelegate::paint(painter, option, index);
}
}
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override {
if (event->type() == QEvent::MouseButtonPress) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (index.column() == index.model()->columnCount() - 1) {
int buttonWidth = option.rect.width() / 3;
QRect buttonRect1 = option.rect.adjusted(0, 0, -2 * buttonWidth, 0);
QRect buttonRect2 = option.rect.adjusted(buttonWidth, 0, -buttonWidth, 0);
QRect buttonRect3 = option.rect.adjusted(2 * buttonWidth, 0, 0, 0);
if (buttonRect1.contains(mouseEvent->pos())) {
emit button1Clicked(index);
} else if (buttonRect2.contains(mouseEvent->pos())) {
emit button2Clicked(index);
} else if (buttonRect3.contains(mouseEvent->pos())) {
emit button3Clicked(index);
}
}
}
return QStyledItemDelegate::editorEvent(event, model, option, index);
}
signals:
void button1Clicked(const QModelIndex &index) const;
void button2Clicked(const QModelIndex &index) const;
void button3Clicked(const QModelIndex &index) const;
};
相关推荐
一、概述
QT是一个跨平台的C++库,主要用来开发图形界面(GUI)程序,它支持多种操作系统 ,如Windows、Linux、Android、ios、gnx、vxworks。
官网:https://w
一、预览
通过窗体-预览 或者 ctrl+R打开预览。
可以使用不同的内置风格、新式表、设备皮肤进行预览。在应用程序可以通过调用QApplication::setStyleSheet()来加载样式表实
代码编辑:
Ctrl + Space: 激活代码补全
Ctrl + /: 注释/取消注释当前行或选定代码
Ctrl + I: 自动缩进选定代码
Ctrl + Shift + U: 转换选定文本为大写
在 Qt 中,输出变量值通常是用于调试目的,你可以使用多种方法来打印或显示变量的值。以下是一些常见的方法:
1、使用 qDebug:
qDebug 是 Qt 中用于输出调试信息的宏。它可以将输出发送到
在 Qt 中全局加载一个 TTF 字体文件并使用它,你可以在程序初始化时期,比如在 main 函数中加载字体。以下是加载全局字体的步骤:
加载字体文件:使用 QFontDatabase::addAp
一、对于窗口 (QMainWindow, QDialog, 等):
1、move() 方法:
使用 move() 方法可以将窗口移动到屏幕上的指定位置。
QMainWindow *window = n
Qt框架中使用new关键字创建的对象通常需要手动释放,但是Qt提供了一种父子关系机制,可以自动管理对象的内存。当你使用new创建一个对象并将其分配给一个父QObject时,这个对象将会在父对象被销毁时
在Qt中,border-radius 在样式表中不会对顶层窗口生效。顶层窗口是指没有父窗口的窗口,通常是您的应用程序的主窗口或者独立的弹出窗口。由于安全性和平台兼容性的原因,很多样式表中的属性在顶层窗
在Qt中,connect函数用于连接信号和槽。从Qt 5开始,你可以使用C++11的lambda表达式作为槽函数,这样可以使你的代码更加简洁,尤其是当你想要对信号进行一些简单的处理时,而不想去定义一个
1. 定义全局常量
全局常量可以在一个头文件中使用 const 关键字或 #define 预处理器来定义:
// constants.h
#ifndef CONSTANTS_H
#define CO