当前位置: 首页 > news >正文

Qt第十四章 模型视图

Model/View(模型/视图)结构

文章目录

  • Model/View(模型/视图)结构
    • 简介
    • 视图组件
    • Model/View结构的一些概念
    • 项目控件组(item Widgets)
    • 模型/视图 如何使用
    • 项目视图组
      • 设置行的颜色交替变换
      • 拖拽
      • 设置编辑操作
      • 其他操作
    • 选择模型
      • 自定义选择多行
      • 全选
    • 代理 Delegate
      • 现有代理
      • 自定义代理
        • 通过QWidget设置代理
        • 通过QPainter设置代理

简介

模型视图结构是Qt中用界面组件显示与编辑数据的一种结构,视图是显示和编辑数据的界面组件,模型是视图与原始数据之间的接口
在这里插入图片描述

视图组件

  • QListView 用于显示单列的列表数据,使用于一维数据的操作
void Widget::initListModel()
{listMod = new QStandardItemModel; // 创建模型ui->listView->setModel(listMod); // 视图设置模型// 增加listMod->appendRow(new QStandardItem("item1")); // 往模型里插入数据for (int i = 2; i < 10; i++)listMod->appendRow(new QStandardItem(QString("item%1").arg(i)));listMod->insertRow(2, new QStandardItem("insert item")); // 在第二行插入新的数据// 删除listMod->removeRows(2, 1); // 从第二行开始删除1个,不包括第二行listMod->removeRow(8); // 删除第九行listMod->takeRow(0); // 移除第一行,内存还在,没被释放// 查找QList<QStandardItem*> findItem = listMod->findItems("item5"); // 查找叫做item5的行,返回所有找到的行listif (findItem.isEmpty())qDebug() << "没找到";elsefor (auto& find : findItem)qDebug() << find->text();QStandardItem* findItem2 = listMod->item(3, 0); // 查找第三行,第0列的元素if (findItem2)qDebug() << findItem2->text();findItem2->setEditable(false); // 设置不可编辑,双击没反应findItem2->setEnabled(false); // 设置不启用,变成灰色findItem2->setData(QString("display item"), Qt::DisplayRole);// 在第五行插入一个元素QMap<int, QVariant> map;map.insert(Qt::DisplayRole, QString("display"));map.insert(Qt::DecorationRole, QColor(0, 0, 255));map.insert(Qt::ToolTipRole, QString("tool tip"));auto it = listMod->item(5);qDebug() << map;listMod->setItemData(it->index(), map);// 自定义数据或角色findItem2->setData(QString("这是自定义角色"), Qt::UserRole + 1);qDebug() << findItem2->data(Qt::UserRole + 1);// 清除角色findItem2->clearData();
}
  • QTreeView 用于显示树状结构的数据
void Widget::initTreeModel()
{treeMod = new QStandardItemModel;ui->treeView->setModel(treeMod);treeMod->appendRow(new QStandardItem("item1"));treeMod->insertRow(1); // 在第一行插入一个空白行QStandardItem* root1 = new QStandardItem("root1");QStandardItem* root2 = new QStandardItem("root2");root1->appendRow(new QStandardItem("sub item"));QList<QStandardItem*> subItem1s;for (int i = 0; i < 5; i++)subItem1s.append(new QStandardItem(QString("su1b%1").arg(i)));QList<QStandardItem*> subItem2s;for (int i = 0; i < 5; i++)subItem2s.append(new QStandardItem(QString("su2b%1").arg(i)));root1->appendRow(subItem1s); // 只添加了su1b0root2->appendRows(subItem2s); // 添加多行treeMod->appendRow(root1);treeMod->appendRow(root2);
}
  • QTableView 显示表格状数据
void Widget::initTableModel()
{tableMod = new QStandardItemModel;ui->tableView->setModel(tableMod);QList<QStandardItem*> items, items1;for (int i = 0; i < 10; i++) {items.append(new QStandardItem(QString("item%1").arg(i)));items1.append(new QStandardItem(QString("abc%1").arg(i)));}tableMod->appendColumn(items1);tableMod->appendRow(items);tableMod->setHorizontalHeaderLabels(QStringList() << "h1"<< "h2"<< "h3"); // 添加水平方向表头
}
  • QColumnView 用多个QListView显示树状层次结构
  • QHeaderView 提供行表头或列表头的视图组件,如QTableView的行表头列表头

Model/View结构的一些概念

在这里插入图片描述

项目控件组(item Widgets)

模型/视图 如何使用

项目视图组

设置行的颜色交替变换

    QPalette palet;palet.setBrush(QPalette::Base, Qt::yellow);palet.setBrush(QPalette::AlternateBase, Qt::green);ui->listView->setPalette(palet);ui->listView->setAlternatingRowColors(true); // 开启颜色交替

拖拽

    ui->tableView->setDragEnabled(true); // 设置可以拖ui->tableView->setDragDropMode(QAbstractItemView::DragDrop); // 支持拖和放

移动内容需要重写事件

设置编辑操作

 ui->listView->setEditTriggers(QListView::AnyKeyPressed); // 设置按下任意键编辑

其他操作

	ui->tableView->setSelectionBehavior(QTableView::SelectRows); // 设置选择方式,默认选择一行ui->tableView->setSortingEnabled(true); // 设置自动排序,默认升序ui->listView->setViewMode(QListView::IconMode); // 设置视图模式为图标视图ui->listView->setFlow(QListView::TopToBottom); // 设置排列丛上到下ui->listView->setResizeMode(QListView::Adjust); // 设置随窗口改变适应布局ui->tableView->hideColumn(8); // 把第八列隐藏ui->tableView->showColumn(8); // 显示ui->tableView->setCornerButtonEnabled(false); // 设置左上角是否允许双击全选,默认是允许的

选择模型

Widget::Widget(QWidget* parent): QWidget(parent), ui(new Ui::Widget), model(new QStandardItemModel)
{ui->setupUi(this);ui->tableView->setModel(model);QList<QStandardItem*> items[5];for (int i = 0; i < 5; i++)for (int j = 0; j < 10; j++)items[i].append(new QStandardItem(QString("item%1").arg(j)));for (int i = 0; i < 5; i++)model->appendColumn(items[i]);// 设置自定义选择区域QItemSelectionModel* selectModel = ui->tableView->selectionModel(); // 获取当前的选择模型QModelIndex leftTop = model->index(0, 0);QModelIndex rightBottom = model->index(4, 2);QItemSelection selection(leftTop, rightBottom);selectModel->select(selection, QItemSelectionModel::Select);// 获取当前选择区域,并且修改它QModelIndexList indexs = selectModel->selectedIndexes();for (auto& i : indexs) {qDebug() << i.data();QStandardItemModel* item = (QStandardItemModel*)i.model();item->setData(i, "123", Qt::DisplayRole);item->setData(i, QIcon("C:/Users/PVer/Pictures/Resource/派蒙.jpeg"), Qt::DecorationRole);}
}

在这里插入图片描述

自定义选择多行

 	QModelIndex idx1 = model->index(0, 0); // 第0行第0列QModelIndex idx2 = model->index(0, 1); // 第0行第1列QModelIndex idx3 = model->index(1, 0); // 第1行第0列QModelIndex idx4 = model->index(0, 2); // 第0行第2列QItemSelection sel(idx1, idx3);QItemSelection sel1(idx2, idx4);selectModel->select(sel, QItemSelectionModel::SelectionFlag(0x0002 | 0x0020)); // 选中0,2行selectModel->select(sel1, QItemSelectionModel::SelectionFlag(0x0002 | 0x0040)); // 选中1,2列

在这里插入图片描述

全选

    QModelIndex topLeft = model->index(0, 0); // 获取左上角QModelIndex bottomRight = model->index(model->rowCount() - 1, model->columnCount() - 1); // 获取右下角QItemSelection selAll(topLeft, bottomRight);selectModel->select(selAll, QItemSelectionModel::Select);

代理 Delegate

代理就是在视图组件上为编辑数据提供编辑器,如在表格组件中编辑一个单元格的数据时,缺省是使用一个QLineEdit编辑框。代理负责从数据模型获取相应的数据,然后显示在编辑器里,修改数据后,又将其保存到数据模型中。

现有代理

视图本身有一个代理,可以编辑

自定义代理

通过QWidget设置代理
  1. 给列表视图加入你创建的代理类
ui->tableView->setItemDelegate(new CustomDelegate); // 设置代理
  1. 创建一个代理的类CustomDelegate继承自QStyledItemDelegate
    头文件
#ifndef CUSTOMDELEGATE_H
#define CUSTOMDELEGATE_H#include <QStyledItemDelegate>
#include <QWidget>class CustomDelegate : public QStyledItemDelegate {Q_OBJECT
public:CustomDelegate(QObject* parent = nullptr);QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override;void setEditorData(QWidget* editor, const QModelIndex& index) const override;void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
};#endif // CUSTOMDELEGATE_H

源文件

#include "CustomDelegate.h"
#include <QSpinBox>CustomDelegate::CustomDelegate(QObject* parent): QStyledItemDelegate(parent)
{
}QWidget* CustomDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{QSpinBox* box = new QSpinBox(parent);box->setMaximum(100);box->setMinimum(0);box->setFrame(false); // 设置微调框不显示边框return box;
}void CustomDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{int v = index.data().toInt();QSpinBox* box = dynamic_cast<QSpinBox*>(editor);box->setValue(v); // 设置微调框里的初始数值
}void CustomDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{QSpinBox* box = dynamic_cast<QSpinBox*>(editor);box->interpretText();int v = box->value();model->setData(index, v, Qt::DisplayRole);
}void CustomDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const
{editor->setGeometry(option.rect); // 设置微调框大小和位置和模型窗口重叠
}
  1. 此处是用微调框做的代理类,效果如图
    在这里插入图片描述
通过QPainter设置代理

QQ聊天的例子
在这里插入图片描述
新建头文件

#ifndef CUSTOMDELEGAT2_H
#define CUSTOMDELEGAT2_H#include <QStyledItemDelegate>
#include <QWidget>class CustomDelegat2 : public QStyledItemDelegate {Q_OBJECT
public:explicit CustomDelegat2(QObject* parent = nullptr);void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override;QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override;void setEditorData(QWidget* editor, const QModelIndex& index) const override;virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;
};#endif // CUSTOMDELEGAT2_H

源文件

#include "CustomDelegat2.h"
#include <QPainter>CustomDelegat2::CustomDelegat2(QObject* parent): QStyledItemDelegate { parent }
{
}void CustomDelegat2::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{QRect area = option.rect; // 获取绘制区域// 获取图标并绘制QRect r1 = QRect(area.topLeft(), QSize(area.width() / 3, area.height()));painter->drawPixmap(r1, QPixmap("C:/Users/PVer/Pictures/Resource/BinQQqq.bmp"));// 绘制名称QRect r2 = QRect(r1.topRight(), QSize(r1.width(), r1.height() / 2));painter->drawText(r2, "梦想盛开的地方");// 绘制消息QRect r3 = QRect(r2.bottomLeft(), r2.size());painter->drawText(r3, "是要做什么的");// 绘制日期QRect r4 = QRect(r2.topRight(), r2.size());painter->drawText(r4, "7-23");
}QSize CustomDelegat2::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{return QSize(option.widget->width(), 50);
}QWidget* CustomDelegat2::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{return new QWidget(parent);
}void CustomDelegat2::setEditorData(QWidget* editor, const QModelIndex& index) const
{
}void CustomDelegat2::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
}

代码里加入树视图,并且设置自定义模型

    listModel = new QStandardItemModel;ui->listView->setModel(listModel);ui->listView->setItemDelegate(new CustomDelegat2);listModel->appendRow(new QStandardItem);listModel->appendRow(new QStandardItem);listModel->appendRow(new QStandardItem);

在这里插入图片描述

http://www.lryc.cn/news/425542.html

相关文章:

  • 硬件工程师必须掌握的MOS管详细知识
  • 希尔排序,详细解析(附图解)
  • 【C语言篇】编译和链接以及预处理介绍(下篇)
  • 利用Llama2 7b自己实现一套离线AI
  • Ciallo~(∠・ω・ )⌒☆第十七篇 Ubuntu基础使用 其一
  • Linux-零拷贝技术
  • 小区团购管理
  • 图像文本擦除无痕迹!复旦提出EAFormer:最新场景文本分割新SOTA!(ECCV`24)
  • Codeforces Round 966 (Div. 3)(A,B,C,D,E,F)
  • 【代码随想录算法训练营第42期 第六天 | LeetCode242.有效的字母异位词、349. 两个数组的交集、202. 快乐数、1. 两数之和】
  • WebRTC音视频开发读书笔记(一)
  • llama3.1本地部署方式
  • 相机光学(三十四)——色差仪颜色观察者视角
  • 思二勋:web3.0是打造应对复杂市场敏捷组织的关键
  • 一文带你快速了解——HAProxy负载均衡
  • 【C++高阶】哈希—— 位图 | 布隆过滤器 | 哈希切分
  • 启发式算法之模拟退火算法
  • 编码器汇总:光学编码器,霍尔编码器,磁性编码器,电容式编码器,单圈编码器,多圈编码器,增量式编码器,绝对值式编码器等
  • 有哪些性价比高的蓝牙耳机可入?四款百万好评实力品牌推荐!
  • MySQL数据库——表的CURD(Update)
  • 性能测试 —— linux服务器搭建JMeter+Grafana+Influxdb监控可视化平台!
  • python基础命令学习
  • 程序设计基础(试题及答案)
  • 日常收录资源
  • 索引——电子学
  • 【学习笔记】A2X通信的协议(九)- 广播远程ID(BRID)
  • HoloLens 和 Unity 空间坐标系统
  • 【npm】如何将开发的vite插件发布到npm
  • 数据结构-查找
  • Ubuntu环境下 pip安装应用时报错