Qt Model_View_学习笔记(格式修改版)
- 格式:pdf
- 大小:409.90 KB
- 文档页数:23
qtableview的用法QTableView是Qt框架中的一个重要的控件,用于显示二维表格数据。
它是基于模型-视图设计模式实现的,可以方便地展示和编辑数据。
本文将介绍QTableView的用法,并详细解释如何使用QTableView显示数据、设置表头、排序、过滤和编辑数据等功能。
一、QTableView的基本用法QTableView是继承自QAbstractItemView的控件,它需要一个数据模型(QAbstractTableModel或QStandardItemModel)来提供数据。
在使用QTableView之前,我们首先需要创建一个QTableView对象,并设置好数据模型。
1. 创建QTableView对象:```cppQTableView *tableView = new QTableView(parent);```2. 设置数据模型:```cppQStandardItemModel *model = new QStandardItemModel(parent); tableView->setModel(model);```3. 设置表格大小:```cpptableView->setFixedSize(width, height);```二、显示数据在设置好数据模型之后,我们可以通过setData()函数向模型中添加数据,并通过setHeaderData()函数设置表头。
1. 添加数据:```cppmodel->setData(model->index(row, column), value);```2. 设置表头:```cppmodel->setHeaderData(column, Qt::Horizontal, headerText);```三、排序和过滤数据QTableView提供了排序和过滤数据的功能,可以方便地对表格中的数据进行排序和筛选。
1. 排序数据:```cpptableView->setSortingEnabled(true);```2. 过滤数据:```cppQSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(parent);proxyModel->setSourceModel(model);tableView->setModel(proxyModel);proxyModel->setFilterRegExp(filterString);```四、编辑数据QTableView还可以编辑数据,我们可以通过设置编辑策略来控制哪些单元格可以编辑。
汇文教育;QFil eInfo类1、q filei nfo提供有关文件系统中的,文件的名称和位置信息(路径),它的访问权限,以及它是否是一个目录或符号链接,该文件的大小和最后修改/读取时间也可用。
2、QFil eInFo可以指向一个文件,一个相对或一个绝对文件路径,绝对文件路径开始与目录分隔符“/”或驱动器的规格(除了在UNI X),相对文件名开始有一个目录名或一个文件名,并指定一个相对于当前工作目录的路径.一个绝对路径的一个例子是一个字符串“/tmp /qua ltz”,相对路径可能看起来像“src / fa tlib”,你可以使用这个函数isrel ative()来检查 qfil einfo是否使用相对或绝对路径的文件,你可以调用函数co nvert toabs()转换 qfil einfo的相对路径为绝对路径。
这q filei nfo文件在构造函数中设置或后setfi le(),使用exi sts()看文件是否存在,si ze()得到它的大小。
加速性能,qf ilein fo缓存文件有关的信息,因为文件可以被其他用户或程序更改,甚至由同一程序的其他部分,这个函数refr esh(),刷新文件信息,如果你想关闭一个qfi leinf o的缓存和强制访问文件系统每次请求信息,你可以调用setCa ching(FALS E).文件的类型是获得通过i sfile(),is dir()和isSy mlink()该文件的日期由 crea ted(), las tModi fied() and last Read(),文件的访问权限由isRe adabl e(),isWri table() an d isE xecut able()获得。
一、介绍Qt是一款跨评台的C++应用程序开发框架,拥有丰富的UI控件库,可以帮助开发者快速构建各种桌面应用程序。
其中,Qt的QTreeView控件是用来显示树形结构数据的控件,通常用于显示文件系统、目录结构、数据分类等。
在本文中,将介绍Qt中QTreeView控件的高级用法,包括自定义数据模型、自定义视图以及树节点的操作等内容。
二、自定义数据模型1. 继承QAbstractItemModel在Qt中,通过继承QAbstractItemModel类可以实现自定义的数据模型。
我们可以根据自己的数据结构和需求来实现自己的数据模型,包括数据的组织方式、展示方式以及数据的增删改查等操作。
2. 实现必要的虚函数在自定义数据模型中,需要实现一些必要的虚函数,包括rowCount()、columnCount()、data()、index()等函数,用来告诉QTreeView控件如何获取数据、显示数据以及处理用户操作等。
3. 使用自定义数据模型创建自定义数据模型后,可以通过setModel()函数将数据模型应用到QTreeView控件中,从而实现树形结构的显示和操作。
三、自定义视图1. 继承QTreeView除了自定义数据模型,Qt还允许开发者自定义QTreeView控件的视图样式。
通过继承QTreeView类并重写相关的绘制函数,可以实现自定义的视图效果,包括节点的样式、展开/折叠的图标以及节点的编辑等功能。
2. 实现p本人ntEvent()函数在自定义QTreeView的视图样式时,通常需要重写p本人ntEvent()函数,以实现节点的自定义绘制效果。
开发者可以根据自己的需求和设计,绘制不同样式的节点、连接线以及展开/折叠的图标等。
3. 使用自定义视图创建自定义的QTreeView视图后,可以通过setView()函数将自定义的视图应用到QTreeView控件中,从而实现不同的视觉效果和交互体验。
四、树节点的操作1. 增加、删除节点在使用QTreeView控件时,通常需要实现对树节点的增加、删除操作。
qtableview的用法一、概述QTableView是Qt框架中的一个重要控件,用于显示和编辑表格数据。
它提供了丰富的功能和灵活的接口,可以满足各种表格数据显示的需求。
本文将详细介绍QTableView的用法,包括数据模型的设置、表头的设置、单元格的编辑以及信号与槽的连接等。
二、数据模型的设置在使用QTableView之前,我们需要先设置数据模型。
数据模型负责提供表格的数据,并将其与QTableView进行关联。
Qt提供了QAbstractTableModel和QStandardItemModel两个常用的数据模型类,我们可以根据实际需求选择其中之一。
1. QAbstractTableModelQAbstractTableModel是一个抽象类,我们需要继承它并实现一些纯虚函数来完成自定义的数据模型。
以下是一个简单的例子:class MyTableModel : public QAbstractTableModel{public:MyTableModel(QObject *parent = nullptr): QAbstractTableModel(parent){// 初始化数据m_data << QVector<QString>{"Alice", "25", "Female"}<< QVector<QString>{"Bob", "30", "Male"}<< QVector<QString>{"Cindy", "28", "Female"};}int rowCount(const QModelIndex &parent = QModelIndex()) const override{if (parent.isValid())return 0;return m_data.size();}int columnCount(const QModelIndex &parent = QModelIndex()) const override{if (parent.isValid())return 0;if (m_data.isEmpty())return 0;return m_data.first().size();}QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override{if (!index.isValid())return QVariant();if (role == Qt::DisplayRole || role == Qt::EditRole)return m_data[index.row()][index.column()];return QVariant();}private:QVector<QVector<QString>> m_data;};在上述代码中,我们定义了一个名为MyTableModel的类,继承自QAbstractTableModel。
Qt中的每个类,都有一个对应的同名头文件,其中包含其类定义。
例如要使用Q Appli catio n类,则需要在程序中添加" #includ e <QAppli catio n>"QAppli catio n类用于管理应用程序范围内的资源。
其构造函数需要main函数的ar gc和ar gv作为参数。
widget被创建时都是不可见的(always create d hidden)。
widget中可容纳其它widg et。
Qt中的wi dget在有用户行为或状态改变时会emi t signal。
signal可以和sl ot函数连接在一起(connec t),这样当有si gnal被emit时,对应的slo t函数会被自动调用。
QWidge t类的构造函数需要一个 QWidge t * 指针作为参数,表示其par ent widget(默认值为0,即不存在pa rentwidget)。
在paren t widget被删除时,Qt会自动删除其所有的child widget。
Qt中有三种Layou t Manage r 类: QHBoxL ayout,QVBoxL ayOut,QGridL ayOut。
基本模式是将widge t添加进L ayOut,由Layou t自动接管widge t的尺寸和位置。
启动Qt程序时可以通过 -style参数改变程序的默认显式风格。
Chapte r 2 Creati ng Dialog s2.1 Subcla ssing DialogQt中所有d ialog的基类是Q Dialo g。
QDialo g派生自Q Widge t。
Qt中所有定义了sig nal或s lot的类,在其类定义的开始处都要使用Q_O BJECT宏。
qtableview用法QTableView是Qt中的一个重要控件之一,用于显示表格数据。
它是Model/View架构的一部分,可以通过模型对其进行QAbstractItemModel的子类,QStandardItemModel的子类或自定义模型进行操作。
在这篇文章中,我们将讨论QTableView的使用方法,并给出一些示例代码来演示如何使用它。
基础功能QTableView是一个展示模型提供的数据的控件。
这些数据可以来自于你自定义的模型,或者是Qt自带的模型类。
在展示数据的同时,QTableView还提供了诸如排序、筛选、编辑等功能。
以下是QTableView的一些基础功能。
数据绑定使用QTableView,首先需要为它绑定一个数据模型。
绑定模型的方式可以是:QAbstractItemModel* model = new QStandardItemModel(4, 4, this);ui->tableView->setModel(model);在这个示例中,我们使用QStandardItemModel类创建了一个4x4的表格,并将其绑定到QTableView中。
排序QTableView支持按照某一列数据进行排序。
这个功能是通过QSortFilterProxyModel实现的。
在排序前需要将绑定的模型设置为QSortFilterProxyModel的子类。
QStandardItemModel* model = new QStandardItemModel(4, 4, this);for(int i=0; i<4; ++i){for(int j=0; j<4; ++j){QStandardItem *item = newQStandardItem(QString("%1, %2").arg(i).arg(j));model->setItem(i, j, item);}}ui->tableView->setModel(model);QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);proxyModel->setSourceModel(model);ui->tableView->setSortingEnabled(true);ui->tableView->setModel(proxyModel);筛选QTableView支持简单的文本筛选功能,默认情况下,它为每一列提供了过滤功能。
Qt学习笔记TableWidget使用说明和增删改操作的实现看一下效果很简单的一个小功能先说分部讲一下过程再给出详细代码添加数据MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow){ui->setupUi(this);ui->tableWidget->setColumnCount(2);ui->tableWidget->setRowCount(2);ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"name"<<"ag e");ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //整行选中的方式ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //禁止修改ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); //设置为可以选中单个ui->tableWidget->setItem(0,0,new QTableWidgetItem("zhangsan"));ui->tableWidget->setItem(0,1,new QTableWidgetItem("1"));ui->tableWidget->verticalHeader()->setVisible(false); //隐藏列表头ui->tableWidget->setItem(1,0,new QTableWidgetItem("lisi"));ui->tableWidget->setItem(1,1,new QTableWidgetItem("20"));ui->tableWidget->selectRow(0);}进行增删除修改操作#include "mainwindow.h"#include "ui_mainwindow.h"#include <QDebug>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow){ui->setupUi(this);ui->tableWidget->setColumnCount(2);ui->tableWidget->setRowCount(2);ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"name"<<"ag e");ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //整行选中的方式ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //禁止修改ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); //设置为可以选中单个ui->tableWidget->setItem(0,0,new QTableWidgetItem("zhangsan"));ui->tableWidget->setItem(0,1,new QTableWidgetItem("1"));ui->tableWidget->verticalHeader()->setVisible(false); //隐藏列表头ui->tableWidget->setItem(1,0,new QTableWidgetItem("lisi"));ui->tableWidget->setItem(1,1,new QTableWidgetItem("20"));ui->tableWidget->selectRow(0);}MainWindow::~MainWindow(){delete ui;}void MainWindow::on_tableWidget_currentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous){if(previous!=Q_NULLPTR){previous->setBackgroundColor(Qt::transparent);}if(current==Q_NULLPTR)return;current->setBackgroundColor(Qt::blue);}void MainWindow::on_btn_Add_clicked(){// QAbstractItemModel *model = ui->tableWidget->model();// model->insertRow(model->rowCount());int cols=ui->tableWidget->columnCount();int rows=ui->tableWidget->rowCount();qDebug()<<rows;ui->tableWidget->insertRow(rows);for(int i=0;i<cols;i++){ui->tableWidget->setItem(rows,i,newQTableWidgetItem("new"+QString::number(rows)));}ui->tableWidget->selectRow(rows);}void MainWindow::on_btn_Del_clicked(){QTableWidgetItem * item = ui->tableWidget->currentItem();if(item==Q_NULLPTR)return;ui->tableWidget->removeRow(item->row());}void MainWindow::on_btn_Modify_clicked(){QModelIndex index = ui->tableWidget->currentIndex();QList<QTableWidgetItem *> listItem =ui->tableWidget->selectedItems();if(listItem.count()==0)return;foreach (QTableWidgetItem * item, listItem) {item->setText("modify");}// QTableWidgetItem * item = ui->tableWidget->currentItem();// if(item==Q_NULLPTR)return;// item->setText("modify");}这里有一些对TableWidget的设置说明一下1. 将表格变为禁止编辑在默认情况下,表格里的字符是可以更改的,比如双击一个单元格,就可以修改原来的内容,如果想禁止用户的这种操作,让这个表格对用户只读,可以这样:tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);QAbstractItemView.NoEditTriggers是QAbstractItemView.EditTrigger枚举中的一个,都是触发修改单元格内容的条件:QAbstractItemView.NoEditTriggers 0 No editing possible. 不能对表格内容进行修改QAbstractItemView.CurrentChanged 1 Editing start whenever current item changes.任何时候都能对单元格修改QAbstractItemView.DoubleClicked 2 Editing starts when an item is double clicked.双击单元格QAbstractItemView.SelectedClicked 4 Editing starts when clicking on an already selected item.单击已选中的内容QAbstractItemView.EditKeyPressed 8 Editing starts when the platform edit key has been pressed over an item.3.单个选中和多个选中的设置:tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); //设置为可以选中多个目标该函数的参数还可以是:QAbstractItemView.NoSelection 不能选择QAbstractItemView.SingleSelection 选中单个目标QAbstractItemView.MultiSelection 选中多个目标QAbstractItemView.ExtendedSelection QAbstractItemView.ContiguousSelect ion 的区别不明显,主要功能是正常情况下是单选,但按下Ctrl或Shift键后,可以多选4. 表格表头的显示与隐藏如果两种都要设置,只要用Qt.AlignHCenter | Qt.AlignVCenter 的方式即可3. 合并单元格效果的实现:tableWidget->setSpan(0, 0, 3, 1) # 其参数为:要改变单元格的1行数2列数要合并的3行数4列数4. 设置单元格的大小首先,可以指定某个行或者列的大小tableWidget->setColumnWidth(3,200);tableWidget->setRowHeight(3,60);还可以将行和列的大小设为与内容相匹配tableWidget->resizeColumnsToContents();tableWidget->resizeRowsToContents();5. 获得单击单元格的内容通过实现itemClicked (QTableWidgetItem *) 信号的槽函数,就可以获得鼠标单击到的单元格指针,进而获得其中的文字信息connect(tableWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),this, SLOT(getItem(QTreeWidgetItem*,int)));//将itemClicked信号与函数getItem绑定6.QTableWidget要调整表格行宽主要涉及以下一个函数resizeColumnsToContents(); 根据内容调整列宽resizeColumnToContents(int col); 根据内容自动调整给定列宽horizontalHeader()->setResizeMode 把给定列设置为给定模式主要模式有Stretch和Fixed7.int row = rowCount();removeRow(row);//清除已有的行列setShowGrid(true);//显示表格线verticalHeader()->setVisible(false);//隐藏左边垂直QHeaderView *headerView = horizontalHeader();headerView->setMovable(false);//去除表头的移动headerView->resizeSection(0,284);//设置第一列宽headerView->resizeSection(1,127);//设置第二列宽headerView->setResizeMode(QHeaderView::Fixed);//列表不能移动headerView->setClickable(false);//不响应鼠标单击setEditTriggers(QTableWidget::NoEditTriggers);//不能编辑setSelectionBehavior(QTableWidget::SelectRows);//一次选中一行setSelectionMode(QAbstractItemView::SingleSelection);//只能单选/*QScrollBar *scrollBar = horizontalScrollBar();scrollBar->hide();*/setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//去掉水平滚动条setVerticalScrollMode(QAbstractItemView::ScrollPerItem);//垂直滚动条按项移动setAutoScroll(false);//去掉自动滚动。
QT学习笔记4:QT中GraphicsView编程⼀、QGraphicsScene1、QGraphicsSceneQGraphicsScene继承⾃QObject,是⼀个管理图元的容器,与QGraphicsView合⽤可以在2D屏幕上显⽰如线、三⾓形、⽂本、⾃定义图元等图元。
QGraphicsScene是不可见的,只⽤于管理图元。
为了查看场景,需要创建⼀个视图组件。
⼀个场景分为三个层:图元层、前景层和背景层。
场景的绘制总是从背景层开始,然后是图形项层,最后是前景层。
2、事件处理与传播QGraphicsScene的责任之⼀是传播来⾃视图的事件。
要发送⼀个事件到场景,需要构造⼀个继承⾃QEvent的事件,使⽤QApplication::sendEvent()函数发送事件。
event()函数负责派发事件到各个图元。
常⽤的事件会被便利事件处理函数处理,如⿏标按下事件会被mousePressEvent()函数处理。
按键事件会被派发到焦点图元。
为了设置焦点图元,可以调⽤setFocusItem()函数,或是图元⾃⾝调⽤QGraphicsItem::setFocus()函数。
调⽤focusItem()函数可以获取当前的焦点图元。
为了兼容图形组件,场景维护着⾃⼰的焦点信息。
默认场景并没有焦点,并且所有的按键事件会别丢弃。
如果setFocus()函数被调⽤,或是场景中⼀个图元获得了焦点,场景会⾃动获得焦点。
如果场景有焦点,hasFocus()函数会返回true,按键事件会被发送到焦点图元。
如果场景失去了焦点,⽽图元有焦点(如调⽤clearFocus()函数),场景会维护图元的焦点信息,⼀旦场景重新获得焦点,会确保最后⼀个有焦点的图元获得焦点。
对于悬停效果,QGraphicsScene会派发悬停事件,如果某个图元接受了悬停事件(调⽤QGraphicsItem::acceptHoverEvents()),当⿏标进⼊图元的区域时,图元会接收到⼀个GraphicsSceneHoverEnter事件。
qt table view使用技巧本文介绍了Qt Table View使用技巧,包括编辑、添加、删除、自定义样式以及排序等。
一、编辑1、双击单元格编辑:双击单元格以编辑其中的内容,在双击之后,编辑框将出现,可以进行编辑,编辑完成后按下回车键保存编辑结果,或者点击表格以外的地方退出编辑模式。
2、重写edit函数:如果想要实现更加丰富的编辑功能,可以重写TableModel类中的edit函数,该函数定义如何处理编辑,可以通过传入参数获取编辑的单元格信息,以及更新表格数据。
3、选择编辑模式:使用QTableView的setEditTriggers函数可以设置编辑模式,可以通过设置的参数来控制通过何种方式进行编辑,如可以控制是否通过双击来进行编辑,是否点击时就进行编辑等。
二、添加1、添加新行:使用insertRow函数可以添加新行,该函数接受一个参数,表示在哪一行之后添加新行,如果参数为-1,则表示添加在最后一行之后,添加完行之后可以再添加行数据,比如新行的列值等等。
2、插入行:使用insertRows函数可以插入多行,该函数接受两个参数,第一个参数表示插入的位置,第二个参数表示要插入多少行,如果第二个参数大于1,则相应多行将被插入,插入完行之后可以再添加行数据。
三、删除1、删除单行:使用removeRow函数可以从表格中删除单行,该函数只接受一个参数,表示要删除哪一行。
2、批量删除:使用removeRows函数可以从表格中批量删除多行,该函数接受两个参数,第一个参数表示从哪一行开始删除,第二个参数表示要删除多少行,如果第二个参数大于1,则相应多行将被删除。
四、自定义样式1、设置字体:使用QTableView的setFont函数可以设置表格的字体,可以设置表格字体的大小、样式以及颜色等。
2、设置单元格颜色:使用QTableView的 setData函数可以设置表格单元格的背景颜色,这样可以根据表格的数据改变单元格的背景颜色,以提供更好的可视化效果。
1、QGridLayoutQGridLayout包含多个grid,它并没有要求其中的每个grid的size相同,通常情况下,每个grid的size是不同的。
对于成员函数addWidget(widget, fromRow, fromColumn, rowSpan, columnSpan, alignment):rowSpan表示新添加进来的widget在垂直方向上跨越或者占据多少个grid。
columnSpan表示新添加进来的widget在水平方向上跨越或者占据多少个grid。
2、line edit的input mask对一个line edit设置了input mask属性后,也就限定了输入字符。
一般情况下,需要填写的字符位置是空白的,但是,你可以让该空白以某个字符占位,你只需在指定input mask 的字符末尾添加―*?‖即可,把‗?‘换为你想用来占位的一个字符。
3、利用designer设计ui总体上来说,先创建各个控件,然后设置layout相对来说好些。
另外,grid layout对设置布局前的窗口布局依赖比较大,即如果设置grid layout前的布局不同,则生效后的差别可能较大。
4、QLabel的buddy属性在qt中,只有QLabel实现了buddy机制。
只有你为QLabel设置了buddy后,文本中的字符‗&‘才能以下划线显示(这点与其他widget 不同),并创建了对应的快捷键(当然,需要+Alt),然后可以利用快捷键迅速的把光标定位到该QLabel的buddy中,例如:QLabel *what = new QLabel(―Find &What:‖);该实例对应快捷键Alt+w。
5、QMouseEvent中的坐标QMouseEvent中保存了两个坐标,一个是全局坐标,当然另外一个是局部坐标。
全局坐标(globalPos())即是桌面屏幕坐标(screen coordinates),这个跟windows下的调用getCursorPos函数得到的结果一致。
Qt Model/View 学习笔记 一.介绍Qt 4推出了一组新的Item View类,它们使用Model/view结构来管理数据与表示层的关系。
这种结构带来的功能上的分离给了开发人员更大的弹性来定制数据项的表示,它也提供一个标准的Model接口,使得更多的数据源可以被这些item view使用。
这里对Model/view的结构进行了描述,结构中的每个组件都进行了解释,给出了一些例子说明了提供的这些类如何使用。
1.1 Model/View结构Model-View-Controller(MVC), 是从Smalltalk发展而来的一种设计模式,常被用于构建用户界面。
经典设计模式的著作中有这样的描述:MVC 由三种对象组成。
Model是应用程序对象,View是它的屏幕表示,Controller定义了用户界面如何对用户输入进行响应。
在MVC之前,用户界面设计倾向于三者揉合在一起,MVC对它们进行了解耦,提高了灵活性与重用性。
假如把view与controller结合在一起,结果就是Model/view结构。
这个结构依然是把数据存储与数据表示进行了分离,它与MVC都基于同样的思想,但它更简单一些。
这种分离使得在几个不同的view上显示同一个数据成为可能,也可以重新实现新的view,而不必改变底层的数据结构。
为了更灵活的对用户输入进行处理,引入了delegate这个概念。
它的好处是,数据项的渲染与编程可以进行定制。
如上图所示,Model与数据源通讯,并提供接口给结构中的别的组件使用。
通讯的性质依赖于数据源的种类与Model实现的方式。
view从Model获取Model Indexes,后者是数据项的引用。
通过把Model Indexes提供给Model,view可以从数据源中获取数据。
在标准的views中,delegate会对数据项进行渲染,当某个数据项被选中时,delegate 通过Model Indexes与Model直接进行交流。
总的来说,Model/view 相关类可以被分成上面所提到的三组:Models,views,delegates。
这些组件通过抽象类来定义,它们有着共同的接口,在某些情况下,还提供了缺省的实现。
抽象类意味着需要子类化以提供完整的其他组件希望的功能。
这也允许实现定制的组件。
Models,views,delegates之间通过信号,槽机制来进行通讯:从Model发出的信号通知view数据源中的数据发生了改变。
从view发出的信号提供了有关被显示的数据项与用户交互的信息。
从delegate发生的信号被用于在编辑时通知Model和view关于当前编辑器的状态信息。
1.1.1 Item Models所有的item Models都基于QAbstractItemModel类,这个类定义了用于views和delegates访问数据的接口。
数据本身不必存储在Model,数据可被置于一个数据结构或另外的类,文件,数据库,或别的程序组件中。
关于Model的基本概念在Model Classes部分中描述。
Qt已经实现过的ItemModel如下:1.QAbstractItemModel提供给数据一个接口,它非常灵活,基本满足views的需要,无论数据用以下任何样的形式表现,如tables,lists,trees。
然而,当你重新实现一个Model时,如果它基于table或list形式的数据结构,最好从QAbstractListModel,QAbstractTableModel开始做起,因为它们提供了适当的常规功能的缺省实现。
这些类可以被子类化以支持特殊的定制需求。
子类化Model的过程在Create New Model部分讨论。
QT提供了一些现成的Models用于处理数据项:2.QStringListModel 用于存储简单的QString列表。
3.QStandardItemModel 管理复杂的树型结构数据项,每项都可以包含任意数据。
4.QDirModel提供本地文件系统中的文件与目录信息。
5.QSqlQueryModel, QSqlTableModel,QSqlRelationTableModel用来访问数据库。
假如这些标准Model不满足你的需要,你应该子类化QAbstractItemModel,QAbstractListModel或是QAbstractTableModel来定制。
1.1.2 Views不同的view都完整实现了各自的功能:QListView把数据显示为一个列表,QTableView 把Model 中的数据以table的形式表现,QTreeView 用具有层次结构的列表来显示Model 中的数据。
这些类都基于QAbstractItemView抽象基类,尽管这些类都是现成的,完整的进行了实现,但它们都可以用于子类化以便满足定制需求。
1.1.3 DelegatesQAbstractItemDelegate 是Model/view架构中的用于delegate的抽象基类。
缺省的delegate实现在QItemDelegate类中提供。
它可以用于Qt标准views的缺省 delegate.1.1.4排序在Model/view架构中,有两种方法进行排序,选择哪种方法依赖于你的底层Model。
假如你的Model是可排序的,也就是它重新实现了QAbstractItemModel::sort()函数,QTableView与QTreeView都提供了API,允许你以编程的方式对Model数据进行排序。
另外,你也可以进行交互方式下的排序(例如,允许用户通过点击view表头的方式对数据进行排序),可以这样做:把QHeaderView::sectionClicked()信号与QTableView::sortByColum()槽或QTreeView::sortByColumn()槽进行联结就好了。
另一种方法是,假如你的Model没有提供需要的接口或是你想用list view表示数据,可以用一个代理Model在用view表示数据之前对你的Model数据结构进行转换。
1.1.5 便利类许多便利类都源于标准的view类,它们方便了那些使用Qt中基于项的view与table类,它们不应该被子类化,它们只是为Qt 3的等价类提供一个熟悉的接口。
这些类有QListWidget,QTreeWidget,QTableWidget,它们提供了如Qt 3中的QListBox, QlistView,QTable 相似的行为。
这些类比View类缺少灵活性,不能用于任意的Models,推介使用Model/view的方法处理数据。
1.2用法简介Qt提供了两个标准的Models:QStandardItemModel和QDirModel。
QStandardItemModel是一个多用途的Model,可用于表示list,table,tree views所需要的各种不同的数据结构。
这个Model也持有数据。
QDirModel维护相关的目录内容的信息,它本身不持有数据,仅是对本地文件系统中的文件与目录的描述。
QDirModel是一个现成的Model,很容易进行配置以用于现存的数据,使用这个Model,可以很好地展示如何给一个现成的view设定Model,研究如何用Model Indexes来操纵数据。
QListView与QTreeView很适合与QDirModel搭配。
下面的例子在tree view与list view显示了相同的信息,QDirModel提供了目录内容数据。
这两个Views共享用户选择,因此每个被选择的项在每个view中都会被高亮。
先装配出一个QDirModel以供使用,再创建views去显示目录的内容。
这给我展示了使用Model的最简单的方式。
Model的创建与使用都在main()函数中完成:int main(int argc,char*argv[]){QApplication app(argc,argv);QSplitter*splitter=new QSplitter;QDirModel*Model=new QDirModel;//从缺省目录创建数据QTreeView*tree=new QTreeView(splitter);tree->setModel(Model);tree->setRootIndex(Model->Index(QDir::currentPath()));QListView*list=new QListView(splitter);list->setModel(Model);list->setRootIndex(Model->Index(QDir::currentPath()));//配置一个view去显示Model中的数据,只需要简单地调用setModel(),并把目录Model作为参数传递//setRootIndex()告诉views显示哪个目录的信息,这需要提供一个Model Index,然后用这个//Model Index去Model中去获取数据//Index()这个函数是QDirModel特有的,通过把一个目录做为参数,得到了需要的Model Index//其他的代码只是窗口show出来,进入程序的事件循环就好了splitter->setWindowTitle("Two views onto the same directory Model");splitter->show();return app.exec();}上面的例子并没有展示如何处理数据项的选择,这包括很多细节,以后会提到。
二.Model类2.1基本概念在Model/view构架中,Model为view和delegates使用数据提供了标准接口。
在Qt 中,标准接口QAbstractItemModel类中被定义。
不管数据在底层以何种数据结构存储,QAabstractItemModel的子类会以层次结构的形式来表示数据,结构中包含了数据项表。
我们按这种约定来访问Model中的数据项,但这个约定不会对如何显示这些数据有任何限制。
数据发生改变时,Model通过信号槽机制来通知关联的views。
如下图所示:2.2 Model Indexes为了使数据存储与数据访问分开,引入了Model Index的概念。
通过Model Index,可以引用Model中的数据项,Views和delegates都使用Indexes来访问数据项,然后再显示出来。
因此,只有Model需要了解如何获取数据,被Model管理的数据类型可以非常广泛地被定义。