提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
翻译|使用教程|编辑:龚雪|2023-02-03 10:34:52.360|阅读 80 次
概述:本教程将为大家介绍每个UI开发人员都应该了解的ModelView编程,欢迎下载相关组件体验~
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
相关链接:
每个UI开发人员都应该了解ModelView编程,本教程的目标是为大家提供一个简单易懂的介绍。
Qt 是目前最先进、最完整的跨平台C++开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。
在上文中,我们主要为大家介绍了Model/View(模型/视图)的一些基本概念(点击这里回顾>>),本文将继续为大家介绍如何创建一个简单的模型/视图应用。
Qt技术交流群:166830288 欢迎一起进群讨论
如果想开发一个模型/视图应用程序,应该从哪里开始呢?我们建议从一个简单的示例开始,逐步扩展它,这使得理解体系结构更加容易。对于许多开发人员来说,在调用IDE之前试图详细理解模型/视图体系结构是不太方便的,从具有演示数据的简单模型/视图应用程序开始实际上更容易。
下面是7个非常简单且独立的应用程序,它们展示了模型/视图编程的不同方面,源代码可以在examples/widgets/tutorials/modelview目录中找到。
从一个使用显示数据的应用程序开始,稍后我们将添加编辑功能。
(文件源:examples/widgets/tutorials/modelview/1_readonly/main.cpp)
// main.cpp #include <QApplication> #include <QTableView> #include "mymodel.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); QTableView tableView; MyModel myModel; tableView.setModel(&myModel); tableView.show(); return a.exec(); }
我们有常用的main()函数:
我们创建了一个MyModel的实例,并使用将它的指针传递给,tableView将调用它接收到的指针的方法来找出两件事:
模型需要一些代码来响应这一点。
我们有一个表数据集,所以从开始,因为它比通用的更容易使用。
(文件源: examples/widgets/tutorials/modelview/1_readonly/mymodel.h)
// mymodel.h #include <QAbstractTableModel> class MyModel : public QAbstractTableModel { Q_OBJECT public: explicit MyModel(QObject *parent = nullptr); int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; };
QAbstractTableModel需要实现三个抽象方法。
(文件源: examples/widgets/tutorials/modelview/1_readonly/mymodel.cpp)
// mymodel.cpp #include "mymodel.h" MyModel::MyModel(QObject *parent) : QAbstractTableModel(parent) { } int MyModel::rowCount(const QModelIndex & /*parent*/) const { return 2; } int MyModel::columnCount(const QModelIndex & /*parent*/) const { return 3; } QVariant MyModel::data(const QModelIndex &index, int role) const { if (role == Qt::DisplayRole) return QString("Row%1, Column%2") .arg(index.row() + 1) .arg(index.column() +1); return QVariant(); }
行数和列数由()和()提供,当视图必须知道单元格的文本是什么时,它调用()方法。行和列信息通过参数index指定,角色设置为,其他角色将在下一节中介绍。在我们的示例中,生成了应该显示的数据,在实际应用程序中,MyModel有一个名为MyData的成员,它作为所有读写操作的目标。
这个小示例演示了模型的被动性质,模型不知道什么时候使用它,也不知道需要哪些数据,它只是在视图每次请求时提供数据。
当模型的数据需要更改时会发生什么?视图如何意识到数据已经改变,需要再次读取?该模型必须发出一个信号,表明单元格的范围发生了变化,这将在2.3节中演示。
除了控制视图显示的文本外,模型还控制文本的外观,当我们稍微改变模型时,得到如下结果:
事实上,除了data()方法之外,没有什么需要更改来设置字体、背景颜色、对齐方式和复选框。下面是data()方法,它产生如上所示的结果。不同之处在于,这次我们使用参数int role根据其值返回不同的信息。
(文件源: examples/widgets/tutorials/modelview/2_formatting/mymodel.cpp)
// mymodel.cpp QVariant MyModel::data(const QModelIndex &index, int role) const { int row = index.row(); int col = index.column(); // generate a log message when this method gets called qDebug() << QString("row %1, col%2, role %3") .arg(row).arg(col).arg(role); switch (role) { case Qt::DisplayRole: if (row == 0 && col == 1) return QString("<--left"); if (row == 1 && col == 1) return QString("right-->"); return QString("Row%1, Column%2") .arg(row + 1) .arg(col +1); case Qt::FontRole: if (row == 0 && col == 0) { // change font only for cell(0,0) QFont boldFont; boldFont.setBold(true); return boldFont; } break; case Qt::BackgroundRole: if (row == 1 && col == 2) // change background only for cell(1,2) return QBrush(Qt::red); break; case Qt::TextAlignmentRole: if (row == 1 && col == 1) // change text alignment only for cell(1,1) return int(Qt::AlignRight | Qt::AlignVCenter); break; case Qt::CheckStateRole: if (row == 1 && col == 0) // add a checkbox to cell(1,0) return Qt::Checked; break; } return QVariant(); }
每个格式化属性将通过对data()方法的单独调用从模型请求,role参数用于让模型知道正在请求哪个属性:
参考Qt命名空间文档了解更多关于 enum功能的信息。
现在我们需要确定使用分离模型如何影响应用程序的性能,因此跟踪视图调用data()方法的频率。为了跟踪视图调用模型的频率,我们在data()方法中放入了一条调试语句,该语句将记录到错误输出流。在我们的小示例中,data()将被调用42次。每次将光标悬停在字段上时,data()将再次被调用——每个单元格调用7次。这就是为什么在调用data()和缓存昂贵的查找操作时,确保数据可用是很重要的。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@cahobeh.cn
文章转载自:慧都网本文将演示如何使用DevExpress WPF Grid控件实现列和带的固定,欢迎下载最新版组件体验!
在本文中,我们将探讨如何通过使用 JxBrowser 和 Quill.js 将现代富文本编辑器嵌入到 Java 桌面应用程序中,来克服 Swing、JavaFX 和 SWT 中内置编辑器的局限性。
Word 文档中的批注通常用于协作审阅和反馈。这些批注可能包含文本和图片,它们为文档改进提供了重要的参考信息。本文将演示如何使用 Spire.Doc for Java 在 Java 中提取 Word 文档中的批注文本和图片。
本文主要介绍如何使用DevExpress WinForms Data Grid组件实现列重新排序,欢迎下载最新版组件体验!
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@cahobeh.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢