Qt中的Model与View 3:从样例出发理解QStringListModel和QListView

目录

Ui文件设计如下:

初始化窗口

这里,就是一经典的例子

你可以看到,我们的环境变量是一个经典的List列表,其中承载的就是我们的字符串。我们现在来仿照着搞一个:

Ui文件设计如下:

我们下面来逐一演示用法。

初始化窗口

首先我们说,Qt的Model View编程必须有Model和对应的显示的View。这里,我们的View已经在Ui设计文件的左下角的ListView出现了,Model呢?则需要我们自己存储住:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QStringListModel>
​
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
​
class MainWindow : public QMainWindow {Q_OBJECT
​
public:MainWindow(QWidget *parent = nullptr);~MainWindow();
private:static constexpr const char *LISTS_DATA_ORG[] = {"Apple", "Banana", "你好", "Shenzhen", "我也不知道写啥了,乐!"};
​QStringList                       original_stringlist;std::unique_ptr<QStringListModel> model;Ui::MainWindow                   *ui;
};
#endif  // MAINWINDOW_H
​

可以看到我们使用了QStringListModel作为存储,当然unique_ptr是一个智能指针,笔者这里习惯使用了,您可以直接使用new分配内存,也行!

MainWindow::MainWindow(QWidget* parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);
​// 初始化StringList列表for (const auto& each : MainWindow::LISTS_DATA_ORG)original_stringlist << each;
​// 初始化一下我们的modelmodel = std::make_unique<QStringListModel>(this);
​model->setStringList(original_stringlist);
​ui->listView->setModel(model.get());::setIfEnableEdit(ui->listView, true);
}

我们的Model的来源就是使用setStringList这接口来设置数据的。之后我们使用其他的例子也是一样,寻找这个Model的设置接口的函数。

不要忘记,我们的Model初始化完成数据之后要交给View显示里面的数据,这里,所有的View都存在接口setModel,请不要忘记调用!

最后的setIfEnableEdit是笔者自己封装的函数,结合上一篇博客所学,我们轻而易举的能写出:

static void setIfEnableEdit(QListView* view, bool is_editable) {is_editable ? view->setEditTriggers(QAbstractItemView::DoubleClicked |QAbstractItemView::SelectedClicked) /* is editable */: view->setEditTriggers(QAbstractItemView::NoEditTriggers); /* is not  editable*/
}

当然,static表达的是文件内部调用不暴露使用,当我们想要使用编辑功能的时候,需要设置view是:QAbstractItemView::DoubleClicked |QAbstractItemView::SelectedClicked(表达的是双击 或者是 点中项再点击选择的意思)。禁用编辑就是不分配触发点击的flag!

void MainWindow::on_btnResumeList_clicked() {model->setStringList(original_stringlist);
}
​
void MainWindow::on_btnListClear_clicked() {model->setStringList({});// model->removeRows(0,m_model->rowCount())
}
​
void MainWindow::on_chkEditable_clicked(bool checked) {::setIfEnableEdit(ui->listView, checked);
}

这三个接口:回复列表,清空列表和允许编辑很好理解,这里不展开

void MainWindow::on_btnListAppend_clicked() {model->insertRow(model->rowCount());auto modelIndex = model->index(model->rowCount() - 1);model->setData(modelIndex, "键入新值");ui->listView->setCurrentIndex(modelIndex);
}
​
void MainWindow::on_btnListInsert_clicked() {auto indexRow = ui->listView->currentIndex().row();if (indexRow == -1) {// 用户没选中, 可以做尾插,也可以提示(这个最好!)return on_btnListAppend_clicked();}model->insertRow(indexRow);auto modelIndex = model->index(indexRow);model->setData(modelIndex, "键入插入的新值!");ui->listView->setCurrentIndex(modelIndex);
}
​
void MainWindow::on_btnListDelete_clicked() {auto indexRow = ui->listView->currentIndex().row();// 当然最合适的还是做用户处理!if (indexRow == -1) return;
​model->removeRow(indexRow);
}

上面插入的和删除的我说一嘴:我们拿到modelIndex是一个索引不是数据本身,数据还是在背后存储的model里。所以我们需要绕个弯取model项!

void MainWindow::on_btnListMoveUp_clicked() {auto indexRow = ui->listView->currentIndex().row();auto index    = QModelIndex();  // ListModel没有父节点if (indexRow == -1) return;
​model->moveRow(index, indexRow, index, indexRow - 1);
}
​
void MainWindow::on_btnListMoveDown_clicked() {auto indexRow = ui->listView->currentIndex().row();auto index    = QModelIndex();  // ListModel没有父节点if (indexRow == -1) return;
​model->moveRow(index, indexRow, index, indexRow + 2);
}

上下移动使用moveRow函数,注意参数名称就告诉你第一个和第三个参数是modelIndex父节点,所以,对于ListView没有父节点的view是传ModelIndex()的默认构造。

void MainWindow::on_btnListSort_clicked() {model->sort(0);
}

sort是对内容的排序,默认是升序,你可以设置第二个参数!

void MainWindow::on_listView_clicked(const QModelIndex& index) {const QString gain_printed_string = QString::asprintf("row: %d, column: %d, data:", index.row(), index.column());const QString gain_data = ui->listView->currentIndex().data().toString();statusBar()->showMessage(gain_printed_string + gain_data);
}
​
​

上面是点击了ListView的项做出的反应,可以一览!

最后是两个显示:

void MainWindow::on_btn_clear_data_clicked() {ui->textEdit->clear();
}
​
void MainWindow::on_btn_fetch_data_clicked() {const QStringList display = model->stringList();for (const auto& each : display) {ui->textEdit->append(each);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/462928.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【VSCode】配置

安装插件 C vscode-icons gdb调试 https://www.bilibili.com/video/BV15U4y1x7b2/?spm_id_from333.999.0.0&vd_sourcedf0ce73d9b9b61e6d4771898f1441f7f https://www.bilibili.com/video/BV1pU4y1W74Z?spm_id_from333.788.recommend_more_video.-1&vd_sourcedf0…

【开发心得】筑梦上海:项目风云录(10)

目录 经典代码背后的故事 贵人相助与价值创造的跳槽哲学 从甲方现场到职场晋升 经典代码背后的故事 写完上一篇故事,本来想休息一段时间,再把思路整理一下。 但是感觉前面的故事里,涉及的故事多,涉及的技术和代码少,很多小伙伴私信希望能够多一些技术和代码的分享。 好…

编译原理第一次实验报告

源代码及附件&#xff1a;编译原理实验一源程序及附件资源-CSDN文库实验题目 实验要求 实验设计 前两部分指出了实验的宏观把控&#xff0c;为了具体实施实验&#xff0c;我们需要预先为实验做出如下设计&#xff1a; 本次实验我选取了C语言的一个子集进行设计词法分析器&…

Elastix-基于ITK的医学图像配准库

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 Elastix是什么&#xff1f; Elastix是一个广泛使用的医学图像配准库&#xff0c;旨在帮助研究人员和临床医生处理和分析医学影像…

清华双臂机器人扩散大模型RDT:先预训练后微调,支持语言、图像、动作多种输入

前言 通过上文介绍的GR2&#xff0c;我们看到了视频生成模型在机器人训练中的应用&#xff0c;无独有偶&#xff0c;和GR2差不多一个时期出来的清华RDT&#xff0c;其模型架构便基于视频生成架构DiT改造而成(当然&#xff0c;该清华团队其实也在DiT之前推出了U-ViT&#xff0c…

远程连接服务

目录 一、远程连接服务器简介 二、连接加密技术简介 三、认证阶段 四、ssh实验 1.修改ssh服务器的端口号 2.拒绝root账户远程登录 3.允许特定用户ssh登录&#xff0c;其他用户无法登录 4.ssh-keygen 一、远程连接服务器简介 概念&#xff1a; 远程连接服务器通过文字或…

YOLOv5之Common.py

文章目录 1.学习目的2.网络模型![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/67b8dbd00c9b4034ba370fc8b8a6031a.jpeg)3.common.py分析 1.学习目的 YOLOv5中最关键一个模型类 2.网络模型 3.common.py分析 # Ultralytics YOLOv5 &#x1f680;, AGPL-3.0 license…

获取Windows计算机信息的一些常用命令

一、获取Windoiws计算机基本信息 1.1、获取系统详细信息 # systeminfo的详细用法帮助命令 systeminfo /? 通过获取系统信息可以了解系统版本内容、硬件信息、域信息和补丁情况。 systeminfo 1.2、获取系统已经启动的服务 # net的详细用法帮助命令 net /? 1.2.1、获取系…

通过 codespaces + ipad 来进行算法训练

目录 零、前言 一、环境搭建 二、DockerFile 2.1 主要流程 2.2 个人模板 零、前言 最近遇到了翘不了的水课&#xff0c;想在课上写题&#xff0c;但是游戏本一个是太重&#xff0c;一个是续航不行&#xff0c;然后想到了在Ipad 上通过云IDE来码题。 一开始用的腾讯云的 C…

部署Prometheus、Grafana、Zipkin、Kiali监控度量Istio

1. 模块简介 Prometheus 是一个开源的监控系统和时间序列数据库。Istio 使用 Prometheus 来记录指标&#xff0c;跟踪 Istio 和网格中的应用程序的健康状况。Grafana 是一个用于分析和监控的开放平台。Grafana 可以连接到各种数据源&#xff0c;并使用图形、表格、热图等将数据…

深入理解Redis的四种模式

Redis是一个内存数据存储系统&#xff0c;支持多种不同的部署模式。以下是Redis的四种主要部署模式。 1、单机模式 单机模式是最简单的部署模式&#xff0c;Redis将数据存储在单个节点上。这个节点包括一个Redis进程和一个持久化存储。单机模式非常适合小型应用程序或者开发和…

uln2003驱动28BYJ-48步进电机

欢迎入群共同学习交流 时间记录&#xff1a;2024/11/2 一、模块解析 1.uln2003 E脚&#xff1a;接GND COM脚&#xff1a;接VCC外部电源 1-7B&#xff1a;输入引脚 1-7C&#xff1a;输出引脚&#xff0c;输入与输出反向 无法输出高电平&#xff0c;外围电路需要接上拉电路…

使用 PyCharm 构建 FastAPI 项目:零基础入门 Web API 开发

使用 PyCharm 构建 FastAPI 项目&#xff1a;零基础入门 Web API 开发 本文提供了一份完整的 FastAPI 入门指南&#xff0c;涵盖从环境搭建、依赖安装到创建并运行一个简单的 FastAPI 应用的各个步骤。通过 FastAPI 和 Uvicorn&#xff0c;开发者可以快速构建现代化的 Web API…

SAP ABAP开发学习——BAPI

目录 业务对象 概念 ​编辑业务对象浏览 BAPI BAPI的浏览 BAPI的调用 BAPI的确认和返回 BAPI的创建 MM/SD常用BAPI 附加&#xff1a;长文本修改 业务对象 概念 业务对象浏览 进入SWO3查看 双击BUS2012 双击下图上方红色位置可以看到BAPI方法的内容 BAPI BAPI(Busines…

《高频电子线路》 —— 电感三端LC振荡器

文章内容来源于【中国大学MOOC 华中科技大学通信&#xff08;高频&#xff09;电子线路精品公开课】&#xff0c;此篇文章仅作为笔记分享。 电感三端LC振荡器 基本原理&#xff08;哈特莱电路&#xff09; 在高频下直流电阻对交流电相阻抗无穷大&#xff0c;相当于开路。谐振回…

它真能替代Express?tinyhttp用速度和轻量征服开发者

它真能替代Express&#xff1f;tinyhttp用速度和轻量征服开发者 如果你是个 Express 粉丝&#xff0c;又经常为它的历史遗留问题头疼&#xff0c;那么有个好消息要告诉你&#xff1a;tinyhttp 来啦&#xff01;这款专注于轻量、快速的 Web 框架正在以一种更现代的方式挑战 Expr…

【时间之外】IT人求职和创业应知【25】

目录 新闻一&#xff1a;AI流量变现财富峰会在深圳举办 新闻二&#xff1a;江苏省加快释放数据要素价值&#xff0c;推动数据产业发展 新闻三&#xff1a;全国大中城市巡回招聘温州站&#xff08;民营企业专场&#xff09;举办 认知决定你的赚钱能力。以下是今天可能影响你求…

qt QGroupBox详解

1、概述 QGroupBox是Qt框架中的一个容器控件&#xff0c;主要用于组织和管理一组相关的控件&#xff08;如按钮、复选框、文本框等&#xff09;&#xff0c;并为这些控件提供一个框架和标题。通过使用QGroupBox&#xff0c;可以创建具有逻辑分组和视觉层次结构的用户界面&…

从 vue 源码看问题 — vue 初始化都做了什么事?

前言 最近想要对 Vue2 源码进行学习&#xff0c;主要目的就是为了后面在学习 Vue3 源码时&#xff0c;可以有一个更好的对比和理解&#xff0c;所以这个系列暂时不会涉及到 Vue3 的内容&#xff0c;但是 Vue3 的核心模块和 Vue2 是一致的&#xff0c;只是在实现上改变了方式、…

nginx系列--(一)--调试环境搭建

辅助脚本&#xff1a; #!/bin/bash mkdir -p $(pwd)/nginxhome # 生成 Makefile,--prefix need a absolute path --with-stream表示要包括stream模块 auto/configure --prefix$(pwd)/nginxhome --with-stream # lsof -i tcp:10086 && fuser -k 10086/tcp ||true # 定…