QT中的模型视图架构(持续更新)

Qt QTreeView简单使用 QTreeView: 用于显示树状结构数据,适用于树状结构数据的操作。 阅读详情

做项目中深深体会到了传统QTreeWidget编辑数据后内存数据、硬盘数据、树形结构数据不同步带来的不便,遂决定学习一下视图模型架构,搜了一些博文,感觉都没有官方教程上讲的流畅,于是写下这篇博客,翻译官方教程并作适当删减。

1.介绍:

  模型/视图架构用于将窗体中展示数据的视图和数据进行分离。标准窗体控件(widget)并没有将数据从视图中分离,所以QT4中存在两种看起来相同但与数据交互不同的组件:widget和view.

  1.1标准窗体组件(widget)

    标准组件通过提供的读写方法能够很方便的将数据整合到程序中,这种方法很直接而且在很多程序中非常有用。但是该方法使用了两份数据,一份在组件中(用于数据展示)一份在组件外(数据文件本身),当对数据进行编辑时,开发人员就必须保证同步两份数据,除此之外数据和数据展示之间的紧耦合关系使得编写单元测试非常困难。

  1.2模型/视图

    模型视图架构更灵活且解决了数据的一致性问题,通过将一个模型传入多个视图,可以轻松做到一份数据对应多个视图。模型/视图架构最大的区别在于,单元格背后并没有存储数据拷贝,他直接操作数据本身。因为view并不知道数据的结构,你需要将你的数据进行包装使它遵从QAbstractItemModel接口,view使用该接口进行数据读写。一个QAbstractItemModel实现类的实例被称作一个模型,一旦view接收到指向model的指针,该view就会读取数据进行展示并且为数据提供编辑器。

  1.3在表格和模型之间使用适配器

    我们可以通过表格直接操作表格中存储的数据,但是使用文本域进行操作会方便的多。模型/视图架构并不能直接将操作一个值(而不是一个数据集)的widget进行model和view的分离(原文:There is no direct model/view counterpart that separates data and views for widgets that operate on one value (QLineEdit,QCheckBox ...) instead of a dataset),所以我们需要一个适配器来连接数据源和表格。

    QDataWidgetMapper是一个很好的解决方案,它能够将一个表单组件映射到数据表中的行,这使得为数据表创建窗体表格非常方便。

    另一个适配器的例子是QCompleter,QCompleter为widget(例如:QComboBox和QLineEdit)提供了自动适配。QCompleter使用一个模型作为数据源。

2.一个简单的模型/视图应用程序

2.1展示数据

先上代码:

//窗体:
ModelViewTest::ModelViewTest(QWidget *parent, Qt::WFlags flags)
	: QMainWindow(parent, flags)
{
	ui.setupUi(this);
	MyModel* myModel = new MyModel(0);
	ui.tableView->setModel(myModel);
}

MyModel.h:

class MyModel : public QAbstractTableModel
{
	Q_OBJECT

public:
	MyModel(QObject *parent);
	~MyModel();

	int rowCount(const QModelIndex& parent = QModelIndex()) const;
	int columnCount(const QModelIndex& parent = QModelIndex()) const;

	QVariant data(const QModelIndex & index, int role = Qt::DisplayRole ) const;
}

MyModel.cpp:
int MyModel::rowCount(const QModelIndex& parent /* = QModelIndex */)const
{
	return 2;
}

int MyModel::columnCount(const QModelIndex& parent /* = QModelIndex */)const
{
	return 3;
}

QVariant MyModel::data(const QModelIndex & index, int role /* = Qt::DisplayRole */ )const
{
	if(role==Qt::DisplayRole)
	{
		return QString("Row%1,Col%2").arg(index.row()).arg(index.column());
	}
	return QVariant();
}

窗体效果如下:

窗体就是普通的代码,通过setModel将自定义的MyModel对象指针传给QTableView,QTableView将会自动调用model中的方法来完成两件事:获取要显示的行数和列数;确定每个单元格中要显示的内容。rowCount、columnCount和data方法皆重写自QAbstractTableModel。值得注意的是,data方法中传入参数role确定了要访问的数据作用(例如:字体、显示、对齐方式等),每个单元格对于每个role都有着对应的数据,通过data方法来请求该数据。将data中代码修改如下,能够体会到role发挥的作用。

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);
		break;
	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)
		{
			QBrush redBackground(Qt::red);
			return redBackground;
		}
		break;
	case Qt::TextAlignmentRole:

		if (row == 1 && col == 1) //change text alignment only for cell(1,1)
		{
			return Qt::AlignRight + Qt::AlignVCenter;
		}
		break;
	case Qt::CheckStateRole:

		if (row == 1 && col == 0) //add a checkbox to cell(1,0)
		{
			return Qt::Checked;
		}
	}
	return QVariant();
}

显示效果:

2.2改变表单中的数据

上面介绍了如何将model数据返回给表单中,那么model中数据改变如何通知表单更新显示呢?下面例子完成了实时显示时间:每隔一秒更新单元格中显示时间。

/在构造函数中设置计时器,每隔一秒发送信号timeout
MyModel::MyModel(QObject *parent)
	: QAbstractTableModel(parent)
{
	mp_timer = new QTimer(this);
	mp_timer->setInterval(1000);
	connect(mp_timer,SIGNAL(timeout()),this,SLOT(timerHit()));
	mp_timer->start();
}
//在0,0单元格内显示时间
QVariant MyModel::data(const QModelIndex &index, int role) const
{
	int row = index.row();
	int col = index.column();
	if(row==0 && col==0)
	{
		return QTime::currentTime().toString("hh::mm::ss");
	}
	return QVariant();
}
//响应timeout信号,发送dataChanged信号,更新表单显示
void MyModel::timerHit()
{
	QModelIndex index = createIndex(0,0);
	emit dataChanged(index,index);
}

关键点在于通过dataChanged信号使表单自动更新显示,该信号在表单数据发生改变时立即触发,两个参数分别是左上角的item和右下角的item,如果参数范围内的item拥有相同的父类,那么他们全部会受到影响,如果拥有不同父类将会导致意想不到的结果。

2.3如何设置表头数据

通过重写headerData方法对表头进行设置,与data方法类似,section为表头单元格,orientation为表头方向

 QVariant MyModel::headerData(int section, Qt::Orientation orientation, int role) const
 {
     if (role == Qt::DisplayRole)
     {
         if (orientation == Qt::Horizontal) {
             switch (section)
             {
             case 0:
                 return QString("first");
             case 1:
                 return QString("second");
             case 2:
                 return QString("third");
             }
         }
     }
     return QVariant();
 }

2.4可编辑表格

在model中加入成员变量QString mp_data[][]来保存单元格中显示的数据,data方法中根据QModelIndex来对应返回mp_data中的数据。可编辑表格需要重写setData和flags方法。falgs方法返回QModelIndex对应单元格拥有的属性(来使单元格可编辑),setData方法会在单元格每次受到编辑时触发,方法内应该完成编辑数据写入到mp_data中。

MyModel.h:


class MyModel : public QAbstractTableModel
{
	Q_OBJECT

public:
	MyModel(QObject *parent);
	~MyModel();

	int rowCount(const QModelIndex& parent = QModelIndex()) const;
	int columnCount(const QModelIndex& parent = QModelIndex()) const;
	QVariant data(const QModelIndex & index, int role = Qt::DisplayRole ) const;
	bool setData(const QModelIndex &index,const QVariant &val,int role=Qt::EditRole);
	Qt::ItemFlags flags(const QModelIndex&index)const;

public slots:

	void timerHit();
private:

	QTimer* mp_timer;

	QString mp_data[2][3];

signals:
	void editCompleted(const QString& str);
	
};

MyModel.cpp:


MyModel::MyModel(QObject *parent)
	: QAbstractTableModel(parent)
{
}

MyModel::~MyModel()
{

}

int MyModel::rowCount(const QModelIndex& parent /* = QModelIndex */)const
{
	return 2;
}

int MyModel::columnCount(const QModelIndex& parent /* = QModelIndex */)const
{
	return 3;
}
QVariant MyModel::data(const QModelIndex &index, int role) const
{
	if (role == Qt::DisplayRole)
	{
		return mp_data[index.row()][index.column()];
	}
	return QVariant();
} 

void MyModel::timerHit()
{
	QModelIndex index = createIndex(0,0);
	emit dataChanged(index,index);
}

bool MyModel::setData(const QModelIndex &index,const QVariant& val,int role/* =Qt::EditRole */)
{
	if(role==Qt::EditRole)
	{
		mp_data[index.row()][index.column()] = val.toString();

		QString result;
		for(int row = 0;row<2;row++)
		{
			for(int col=0;col<3;col++)
			{
				result+=mp_data[row][col]+" ";
			}
		}
		//emit editCompleted(result);
	}
	return true; 
}


Qt::ItemFlags MyModel::flags(const QModelIndex& index) const
{
	 return Qt::ItemIsSelectable |  Qt::ItemIsEditable | Qt::ItemIsEnabled ;
}

注意:函数的入参中QModelIndex一定要是引用,否则会设置无效。

2.5TreeView的使用

TreeView的使用和TableView基本一致,区别在于TreeVIew中的iem之间拥有层级(父子)关系。QStandardItemModel是专为层级数据设计的容器且继承自QAbstractItemModel,TreeView与QStandardItemModel搭配使合适。

在TreeView中插入item:

QTreeViewTest::QTreeViewTest(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	QStandardItemModel* standItemModel = new QStandardItemModel();

	QList<QStandardItem*> prepareRow1;
	prepareRow1<<new QStandardItem("first");
	prepareRow1<<new QStandardItem("second");
	prepareRow1<<new QStandardItem("third");

	QList<QStandardItem*> prepareRow2;
	prepareRow2<<new QStandardItem("111");
	prepareRow2<<new QStandardItem("222");
	prepareRow2<<new QStandardItem("333");

	QStandardItem* rootItem = standItemModel->invisibleRootItem();
	rootItem->appendRow(prepareRow1);
	prepareRow1.first()->appendRow(prepareRow2);

	ui.treeView->setModel(standItemModel);
	ui.treeView->expandAll();
}

效果如下:

捕捉选中节点并获取节点数据:TreeView通过一个单独的selection model对象来管理选中对象,该对象通过selectionModel方法可以获取,获取到selection model对象后通过selectionChanged信号来绑定相应的槽函数。

例子:当选中treeView中的节点时将窗体标题设置为节点显示内容

QTreeViewTest::QTreeViewTest(QWidget *parent)
	: QMainWindow(parent)
{

	ui.setupUi(this);
        QStandardItemModel *standardItemModel = new QStandardItemModel();
	QStandardItem* rootNode = standardItemModel->invisibleRootItem();

	QStandardItem *americaItem = new QStandardItem("America");
	QStandardItem *mexicoItem =  new QStandardItem("Canada");
	QStandardItem *usaItem =     new QStandardItem("USA");
	QStandardItem *bostonItem =  new QStandardItem("Boston");
	QStandardItem *europeItem =  new QStandardItem("Europe");
	QStandardItem *italyItem =   new QStandardItem("Italy");
	QStandardItem *romeItem =    new QStandardItem("Rome");
	QStandardItem *veronaItem =  new QStandardItem("Verona");

	rootNode->    appendRow(americaItem);
	rootNode->    appendRow(europeItem);
	americaItem-> appendRow(mexicoItem);
	americaItem-> appendRow(usaItem);
	usaItem->     appendRow(bostonItem);
	europeItem->  appendRow(italyItem);
	italyItem->   appendRow(romeItem);
	italyItem->   appendRow(veronaItem);
	
	ui.treeView->setModel(standardItemModel);
	ui.treeView->expandAll();

	QItemSelectionModel *selectionModel = ui.treeView->selectionModel();
	connect(selectionModel, SIGNAL(selectionChanged (const QItemSelection &, const QItemSelection &)),
		this, SLOT(selectionChangedSlot(const QItemSelection &, const QItemSelection &)));
}


void QTreeViewTest::selectionChangedSlot(const QItemSelection & /*newSelection*/, const QItemSelection & /*oldSelection*/)
{
	//get the text of the selected item
	const QModelIndex index = ui.treeView->selectionModel()->currentIndex();
	QString selectedText = index.data(Qt::DisplayRole).toString();
	//find out the hierarchy level of the selected item
	int hierarchyLevel=1;
	QModelIndex seekRoot = index;
	while(seekRoot.parent() != QModelIndex())
	{
		seekRoot = seekRoot.parent();
		hierarchyLevel++;
	}
	QString showString = QString("%1, Level %2").arg(selectedText)
		.arg(hierarchyLevel);
	setWindowTitle(showString);
}

通过 treeView->selectionModel()->currrentIndex获取当前选中节点的Model index,通过model index获取节点中的内容。顶层节点的parent()方法会返回一个默认构造的QModelIndex对象,以此来判断当前节点是否是顶层节点。

通过QAbstractItemView::setSelectionModel方法来为view设置selection model,以此可以实现多个view使用同一个selection model,只需要获取其中一个的selection model然后再设置给其他view。

2.6 预定义的Model

典型的使用模型视图架构的方式是将数据进行封装使其适配view类,Qt也未一些通用的数据结构预定义了一些常用的model:

3.0 委托

到目前为止的所有例子我们都在显示和编辑文本数据,提供数据显示和编辑服务的组件叫做委托,view会有一个默认委托。但是如果我们想在单元格中编辑图片或者将数据显示为图形样式,我们就需要自己设置委托。

 

我懂了,原来这就是4+1架构视图模型 他在1995年的《IEEE Software》上发表了题为《The 4+1 View Model of Architecture》的论文,这一论文的发表引起了业界的极大关注,并最终被RUP(Rational Unified Process,统一软件开发过程)采纳,现在已经成为架构设计的结构标准。从前面的图可以看到,4+1中的4个视图都是围绕着场景视图为核心的。逻辑视图、开发视图和部署视图,描述的都是系统的静态信息,到现在为止我们还缺少对系统动态行为的描述,而运行视图就是用来描述系统中的动态信息的。 阅读详情

相关推荐

2024年《Qt基础教程之Qt学习之路》,写给正在求职的物联网嵌入式开发开发

点,真正体系化!**

2401_85013415的博客 413

Qt模型/视图结构

Qt模型

m0_73443478的博客 349

Qt知识点总结。。。持续更新

使用引用参数的两个原因:1)程序员能够修改调用函数中的数据对象;2)通过传递引用而不是整个数据对象,可以提高程序的运行效率。(当数据对象比较大时——结构或者类对象)使用值传递、引用传递、指针传递原则:原则选择:1)数据对象很小,eg:内置数据类型、小型结构;使用按值传递;2)数据对象是数组,则使用指针,这是唯一选择,并将指针声明指向const的指针;3)数据对象是较大的结构,则使用const指针或者const引用,优点是提高程序的效率,节省复制结构所需的时间和空间;

qq_37464701的博客 1222

Qt树形控件QTreeView使用1——节点的添加删除操作 复选框的设置

QtreeView是ui中最常用的控件,Qt中QTreeWidget比QTreeView更简单,但没有QTreeView那么灵活(QTreeWidget封装的和MFC的CTreeCtrl很类似,没有mvc的特点)。 1. QStandardItemModel在QTreeView中的使用 使用QTreeView的对应模型是QStandardItemModel,这个是Qt对应ui界面最有用

huyisu的专栏 3万+

Qt —— QTableView委托代理之模型视图的应用(附视频介绍)

     QTableView实现一个表视图,显示模型中的项。该类用于提供以前由QTABLE类提供的标准表,但使用QT的Meave/VIEW体系结构提供的更灵活的方法。QTableView类是模型/视图类之一,是Qt模型/视图框架的一部分。QTableView实现qabstractemview类定义的接口,以允许它显示从qabstractemmodel类派生的模型提供的数据。      可以通过用...

824

Qt实现高级组织结构图

运用Qt框架实现的高级组织结构图,可支持添加、删除、剪切、复制、粘贴、插入超链接、插入背景图片、属性查看等功能,可供学习及研究。

一文搞懂Qt模型视图框架:MVC/MVD架构详解与实战(Awesome_Qt_Learning)

Awesome_Qt_Learning 是一个 2025 年 Qt 开发学习资源库,系统化收录了从 Qt 基础到实战项目的资料、书籍与面试题。本文带你一文搞懂 **Qt 模型视图框架(Model/View Framework)** 的核心思想,讲清楚 MVC 与 MVD 架构的区别,并给出新手快速上手模型视图实战的学习路径。 ## 📌 什么是 Qt 模型视图框架? 简单说,**Qt 模型视图

gitblog_00776的博客 1102

Qt QTreeView使用-QStandardItemModel的使用

代码里面有tree view的节点操作,包括添加,当前点击检查,遍历等。具体介绍见: Qt树形控件QTreeView使用1——节点的添加删除操作: http://blog.youkuaiyun.com/czyt1988/article/details/18996407 Qt树形控件QTreeView使用2——复选框的设置: http://blog.youkuaiyun.com/czyt1988/article/details/19171727 利用C++11的function和bind功能,实现QStandardItemModel的通用遍历函数: http://blog.youkuaiyun.com/czyt1988/article/details/21093451

【QT】-- 模型与视图简介

Qt模型/视图结构简介 Qt的Model/View结构将界面组件与数据分离,通过模型作为中间层进行数据管理。模型负责与原始数据交互,视图负责界面显示,代理处理数据编辑。核心组件包括: 模型:QAbstractItemModel的子类(如QStandardItemModel、QFileSystemModel) 视图:QListView、QTreeView、QTableView等显示组件 代理:负责数据编辑的中间件 该结构采用表格层次组织数据,通过模型索引(QModelIndex)定位数据项。每个数据项具有行号

羊小猪~~的博客 628

STM32+ESP8266接入OneNet物联网平台全流程

MQTT协议是物联网设备与云平台通信的主流轻量级消息传输标准,其发布/订阅模型天然适配嵌入式资源受限场景;OneJSON作为中国移动OneNet平台定制的数据格式,在标准JSON基础上精简Schema、降低解析开销,显著提升STM32等MCU的处理效率。该技术组合兼顾安全性、低功耗与工程可量产性,广泛应用于环境监测、智能仪表、工业传感器等远程数据采集系统。实际落地需协同完成云平台物模型定义、Token动态认证、MQTT Topic严格构造、AT指令可靠交互及单总线传感器数据融合等关键环节。本文以DS18B2

u5v6w7的博客 1120

英飞凌AURIX™ Development Studio(ADS)工程调试与烧录实战指南

本文详细介绍了英飞凌AURIX™ Development Studio(ADS)的工程调试与烧录实战指南。从调试环境搭建、硬件连接到断点设置、变量监控等核心调试技巧,帮助开发者快速掌握ADS安装使用教程,提升多核处理器开发效率。

k8l9m0n的博客 574

Qt模型 视图教程_qstandarditemmodel怎么导入

每个UI开发者都应该要知道(Model/View)编程,本教程提供了一个关于该话题的一个易于理解的引导。表格,列表和树widget是在GUI编程中频繁使用的组件。这些widget有两种不同的方式去访问它们的数据。传统的方式是使用内部存有数据的widget,这种方式非常直观,但是在许多特殊的应用程序中,它会导致问题。第二种方式是模型/视图编程,widget内部不包含存放数据的容器,这些widget通过一个去访问外部数据,因此避免了数据冗余。

2401_85014296的博客 1034

S/4中的16种特殊库存类型

S/4中的16种特殊库存类型

yanzibing99的博客 1万+

Qt的命名空间(持续更新)

在写码的过程中经常遇到Qt::xxx,其实用着用着也就习惯了,但是为了做到融会贯通和知其所以然,决定把遇到的枚举常量记录下来加强印象 文章目录enum Qt::ItemDataRole enum Qt::ItemDataRole 模型中的每一个项目中都有一个与之关联的数据和项目角色,视图使用角色来想模型表示其所需要的数据的类型,定制的模型需要使用下面的类型类返回数据。 常用的角色如下所示: ...

赵树成的博客 1426

COMSOL模拟CO2驱替CH4:多物理场耦合建模与工程应用详解

在非常规天然气开发与碳封存工程中,多孔介质内的渗流、吸附与岩石变形相互耦合,使得CO2驱替CH4的产能预测和CO2封存评估无法仅靠经验公式完成。以达西定律描述裂隙流动、以扩展Langmuir方程刻画竞争吸附、用应力-吸附-渗透率关系关联煤岩变形,是多物理场耦合数值模拟的核心路径。COMSOL Multiphysics凭借内置渗流、固体力学与组分传递接口,能够将这些机制整合为可参数化扫描的仿真模型,为注气压力、井距、渗透率演化等方案设计提供量化依据。围绕CO2驱替CH4模拟的建模流程、参数取法与结果判读,可形

weixin_29574585的博客 162

别再死记硬背了!用Python+Matlab/Simulink手把手带你理解PID控制器的‘稳、快、准’

本文通过Python编程和Matlab/Simulink仿真,深入解析PID控制器的‘稳、快、准’三大核心指标,帮助读者直观理解PID控制的实现原理与参数整定技巧。内容涵盖经典控制理论和自动控制原理,提供实战案例和高级调参技巧,适合工业自动化领域的学习者和工程师。

weixin_42551227的博客 369

【Qt】图形视图框架QGraphics(持续更新)

(讲述内容是标题的两个组件,为了打字方便 ,以下简称View和Scene) Scene是画布,View是试图,我们在画布上绘图,然后在视图上显示出来。 为什么要使用这些组件?因为它们是面向对象的绘图,比较方便。 QGraphicsView继承于QAbstractScollArea,也就是说可以滚动的 QGraphicsScene继承于QObject,不是Widget 定义View,注意动态分配空间...

weixin_41106066的博客 4191

JavaScript 书签脚本实战:腾讯/优酷/爱奇艺等5大视频站m3u8链接一键提取

本文详细介绍了如何使用JavaScript书签脚本一键提取腾讯视频、优酷、爱奇艺等五大视频平台的m3u8流媒体链接。通过分析播放器内部对象结构,开发者可以高效获取视频源文件,避免录屏画质损失。文章包含各平台适配方案、实战增强功能开发及企业级解决方案设计,帮助用户快速掌握这一实用技术。

weixin_27945229的博客 611

Qt开发技术:图形视图框架(一)基本介绍

图形视图框架(The Graphic View Framework)用于管理和与大量定制的二维图形项目交互,以及用于可视化项目的视图小部件,支持缩放和旋转。

长沙红胖子 Qt・西安|省级科研团队从业背景,深耕双一流体系高精尖技术配套研发|剥离高精尖机理,沉淀高端特种行业领域 Qt 工程化落地经验|博文仅分享通用技术总结,输出公开普适工程思路。 4万+

第076篇:大涡模拟进阶

大涡模拟(Large Eddy Simulation, LES)是介于直接数值模拟(DNS)和雷诺平均方法(RANS)之间的重要湍流模拟方法。本文深入介绍动态Smagorinsky模型、尺度相似模型、WALE模型和隐式LES等高级亚格子模型。通过Python实现槽道湍流和圆柱绕流的LES求解器,详细展示近壁面处理、动态系数计算和亚格子应力建模技术。大涡模拟,亚格子模型,动态模型,Smagorinsky,WALE模型,尺度相似模型,近壁面处理,槽道湍流LES的核心思想是对Navier-Stokes方程进行空间

2401_87715305的博客 740

A.特定领域知识图谱知识推理方案:知识图谱推理算法综述[五]-GeniePath会自动过滤多度“邻居“的图神经网络算法。

构图对于GNN格外重要。那么怎样构图才有信息、有意义呢?如果节点的邻居只有自己,即邻接矩阵为对角阵时,GNN会退化成一个DNN模型。图中每个节点都是孤立的,相当图信息并不能相比其他方法带来增益。如果图特别稠密,比如是一个clique,即每个节点都和所有其他节点有边连接。同样的,这样的图信息同样是信息熵为0。经验上讲,节点度分布有区分度的图是相对有价值的。查看图的节点度分布。比如二类分类,分析正负例的图拓扑当然,构图和实际场景强相关。

丨汀、的博客 437

2024年最新Qt模型 视图教程_qstandarditemmodel怎么导入(1),离开小厂进大厂的第一周

表格,列表和树widget是在GUI编程中频繁使用的组件。这些widget有两种不同的方式去访问它们的数据。传统的方式是使用内部存有数据的widget,这种方式非常直观,但是在许多特殊的应用程序中,它会导致问题。第二种方式是模型/视图编程,widget内部不包含存放数据的容器,这些widget通过一个去访问外部数据,因此避免了数据冗余。这看起来似乎很复杂,但是一旦你深入研究,它不但易于掌握,而且模型/视图编程的许多好处都将慢慢呈现。

2401_84976110的博客 1157

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Qt Quick 开发基础 + 实战(持续更新中…)

-

遇己 5189

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Qt5开发从入门到精通——第八篇四节( 模型/视图结构—— 代理 (Delegate))

本章节会给大家带来模型/视图结构—— 代理 (Delegate)的开发实例详解。在表格中嵌入各种不同控件,通过表格中的控件对编辑的内容进行限定。通常情况下,采用这种在表格中插入控件的方式,控件始终显示。当表格中控件数目较多时,将影响表格的美观。此时,可利用 Delegate 的方式实现同样的效果,控件只有在需要编辑数据项时才会显示,从而解决了所遇到的上述问题。模型/视图结构—— 代理 (Delegate)会在应用程序开发中经常用到的。

weixin_44759598的博客 2115

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Qt5开发从入门到精通——第八篇一节(模型/视图结构—— 文件目录浏览器)

本章节会给大家带来模型/视图结构的概述及文件目录浏览器的实例。MVC 设计模式是起源于 Smalltalk 的一种与用户界面相关的设计模式。通过使用此模式,可以有效地分离数据和用户界面。MVC 设计模式包括三个元素:表示数据的模型 (Model) 、表示用户界面的视图 (View) 和定义了用户在界面上操作的控制器 (Controller)。与 MVC 设计模式类似, Qt 引入了模型/视图结构用千完成数据与界面的分离,即 InterView框架。

weixin_44759598的博客 996

Qt高级用法以及日志输出,持续更新

QPaintEngine 类用在 QPainter 和 QPaintDevice 之间,通常情况下对开发人员而言它是透明的,我们无需重新定义 QPaintEngine ,除非需。动态类型转换使用dynamic_cast运算符进行,是程序在运行的过程中进行类型转换,转换不成功会返回空指针或者抛出异常。translate(width() / 2, height() / 2)代表将原点平移到窗口中心位置。// 删除赋值运算符。中,exec函数中的消息循环返回,exec函数也退出,最后返回到调用对话框的代码处。

weixin_41199566的博客 1398
上一篇: C++实现文本编码判断
下一篇: 算法学习之-基本排序算法(时间复杂度O(n^2))
angry ant
博客等级 码龄10年 9粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值