使用预定义模型

Qt提供了几种可以在视图类中使用的预定义模型,见下表。

Team Leaders

我们从一个简单的对话框开始,用户可以使用它添加、删除和编辑一个 QStringList,其中每个字符串都代表一个团队领导。

TeamLeadersDialog.h

#ifndef TEAMLEADERSDIALOG_H
#define TEAMLEADERSDIALOG_H#include <QDialog>class QDialogButtonBox;
class QListView;
class QStringListModel;class TeamLeadersDialog : public QDialog
{Q_OBJECTpublic:TeamLeadersDialog(const QStringList &leaders, QWidget *parent = 0);QStringList leaders() const;private slots:void insert();void del();private:QListView *listView;QDialogButtonBox *buttonBox;QStringListModel *model;   // 存储一个字符串列表
};#endif

TeamLeadersDialog.cpp

#include <QtGui>#include "teamleadersdialog.h"TeamLeadersDialog::TeamLeadersDialog(const QStringList &leaders,QWidget *parent): QDialog(parent)
{model = new QStringListModel(this);model->setStringList(leaders);listView = new QListView;listView->setModel(model);listView->setEditTriggers(QAbstractItemView::AnyKeyPressed      /* 按任意键编辑 */| QAbstractItemView::DoubleClicked); /* 双击编辑 */buttonBox = new QDialogButtonBox();QPushButton *insertButton = buttonBox->addButton(tr("&Insert"),QDialogButtonBox::ActionRole);QPushButton *deleteButton = buttonBox->addButton(tr("&Delete"),QDialogButtonBox::ActionRole);buttonBox->addButton(QDialogButtonBox::Ok);buttonBox->addButton(QDialogButtonBox::Cancel);connect(insertButton, SIGNAL(clicked()), this, SLOT(insert()));connect(deleteButton, SIGNAL(clicked()), this, SLOT(del()));connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));QVBoxLayout *mainLayout = new QVBoxLayout;mainLayout->addWidget(listView);mainLayout->addWidget(buttonBox);setLayout(mainLayout);setWindowTitle(tr("Team Leaders"));
}QStringList TeamLeadersDialog::leaders() const
{return model->stringList();
}void TeamLeadersDialog::insert()
{int row = listView->currentIndex().row();model->insertRows(row, 1);QModelIndex index = model->index(row);listView->setCurrentIndex(index);listView->edit(index);
}void TeamLeadersDialog::del()
{model->removeRows(listView->currentIndex().row(), 1);
}

TeamLeadersDialog()
我们从创建并且组装一个 QStringListModel 开始。接下来创建一个 ListView 并且把刚才创建的那个模型作为它的模型;还设置了一些编辑触发器以允许用户简单地通过开始输入或者双击进人编辑字符串的状态。默认情况下,ListView 中没有任何编辑触发器,这样就使这个视图只读。

insert()
当用户单击由此按钮的时候, insert()槽就会得到调用这个糟从获得到表视图的当前项的行数开始。模型中的每一个数据项都对应一个"模型索引",它是由一个QModelIndex 对象表示的。会在下一节中看到有关模型索引的细节,但是现在我们需要知道一个索引有三个主要组成部分:行、列和它所属的模型的指针。在一个一维的列表视图中,列总为0。

一旦得到行数,就可以在那个位置插入一个新行。这个插入是在模型中完成的,并且模型会自动更新列表视图。然后我们设置刚刚插入的空白行为列表视图的当前索引。最后,设置列表视图在当前行进入编辑的状态,就好像用户已经按下一个键或者双击进编辑状态一样。

del()
在构造函数中, Delete 按钮的 clicked() 信号会连接到这个 del() 槽。因为我们只是想删除当前行,所以可以使用当前索引位置调用 removeRows() ,并且把要删除的行数设置为 1。就像刚才的插入操作一样,我们需要依赖于模型才能够相应地更新这个视图。

leaders()
最后,当关闭这个对话框的时候, leader() 函数提供了一种读回这些被编辑的宇符串的方式。

main.cpp

#include <QApplication>#include "teamleadersdialog.h"int main(int argc, char *argv[])
{QApplication app(argc, argv);QStringList leaders;leaders << "Stooge Viller" << "Littleface" << "B-B Eyes"<< "Pruneface" << "Mrs. Pruneface" << "The Brow"<< "Vitamin Flintheart" << "Flattop Sr." << "Shakey"<< "Breathless Mahoney" << "Mumbles" << "Shoulders"<< "Sketch Paree";TeamLeadersDialog dialog(leaders);dialog.show();return app.exec();
}

通过简单地改变 TeamLeadersDialog 的窗口标题,它就可以成为一个通用的字符串列表编辑对话框。我们通常所需要的另外一个通用对话框是向用户显示一个文件或者目录的列表。

Directory Viewer

这个例子使用了QDirModel类,它封装了计算机的文件系统并且可以显示(或者隐藏)不同的文件属性。可以为这个模型应用过滤器,这样就可以根据自己的需要显示不同类型的文件系统条目,并且使用不同的方式对这些条目进行排序。

DirectoryViewer.h

#ifndef DIRECTORYVIEWER_H
#define DIRECTORYVIEWER_H#include <QDialog>class QDialogButtonBox;
class QDirModel;
class QTreeView;class DirectoryViewer : public QDialog
{Q_OBJECTpublic:DirectoryViewer(QWidget *parent = 0);private slots:void createDirectory();void remove();private:QTreeView *treeView;QDirModel *model;QDialogButtonBox *buttonBox;
};#endif

DirectoryViewer.cpp

#include <QtGui>#include "directoryviewer.h"DirectoryViewer::DirectoryViewer(QWidget *parent): QDialog(parent)
{model = new QDirModel;model->setReadOnly(false);model->setSorting(QDir::DirsFirst | QDir::IgnoreCase | QDir::Name);treeView = new QTreeView;treeView->setModel(model);treeView->header()->setStretchLastSection(true);treeView->header()->setSortIndicator(0, Qt::AscendingOrder);treeView->header()->setSortIndicatorShown(true);treeView->header()->setClickable(true);QModelIndex index = model->index(QDir::currentPath());treeView->expand(index);    // ???treeView->scrollTo(index);  // 打开父对象,到根节点 滚动到当前项treeView->resizeColumnToContents(0);buttonBox = new QDialogButtonBox(Qt::Horizontal);QPushButton *mkdirButton = buttonBox->addButton(tr("&Create Directory..."), QDialogButtonBox::ActionRole);QPushButton *removeButton = buttonBox->addButton(tr("&Remove"),QDialogButtonBox::ActionRole);buttonBox->addButton(tr("&Quit"), QDialogButtonBox::AcceptRole);connect(mkdirButton, SIGNAL(clicked()), this, SLOT(createDirectory()));connect(removeButton, SIGNAL(clicked()), this, SLOT(remove()));connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));QVBoxLayout *mainLayout = new QVBoxLayout;mainLayout->addWidget(treeView);mainLayout->addWidget(buttonBox);setLayout(mainLayout);setWindowTitle(tr("Directory Viewer"));
}void DirectoryViewer::createDirectory()
{QModelIndex index = treeView->currentIndex();if (!index.isValid())return;QString dirName = QInputDialog::getText(this,tr("Create Directory"),tr("Directory name"));if (!dirName.isEmpty()) {if (!model->mkdir(index, dirName).isValid())QMessageBox::information(this, tr("Create Directory"),tr("Failed to create the directory"));}
}void DirectoryViewer::remove()
{QModelIndex index = treeView->currentIndex();if (!index.isValid())return;bool ok;if (model->fileInfo(index).isDir()) {ok = model->rmdir(index);    // 删除文件夹} else {ok = model->remove(index);   // 删除文件}if (!ok)QMessageBox::information(this, tr("Remove"),tr("Failed to remove %1").arg(model->fileName(index)));
}

DirectoryViewer()
一旦模型构造完成,我们就让它可编辑并且设置不同的初始排序属性。然后创建用于显示这个模型的数据的 QTreeView。这个 QTreeVìew 的头可以用来提供用户控制的排序功能。通过让头可以点击,用户就能够按他们所点击的列进行排序。当这个树视图的头被设置完毕之后,就得到了当前目录的模型索引,然后通过调用 expand(),如果需要就打开它的父对象一直到根节点,并且调用 scrollTo()滚动到当前项,这样就确保它是可见的。然后我们确保第一列足够宽,可以显示它所有的条目,而不是使用省略号。

这里没有给出的构造函数中的部分代码中,把 Create Directory Remove 按钮和实现这些操作的槽连接起来。我们不需要 Rename 按钮,这是因为用户可以通过按下凹键并键入字母来直接进行重命名。

createDirectory()
如果用户在输入对话框中输入的是一个目录名称,就试图会在当前目录下用这个名称创建一个子目录。QDirModel::mkdir() 函数可以使用父目录的索引和新目录的名称,然后返回它所创建的目录的模型索引。如果操作失败,就返回一个无效的模型索引。

remove()
如果用户单击Remove,就试图移除当前项所对应的文件或者目录。也可以使用QDir来完成这项操作,但是QDirModel提供了一些对QModelIndex起作用的方便函数。

main.cpp

#include <QApplication>#include "directoryviewer.h"int main(int argc, char *argv[])
{QApplication app(argc, argv);DirectoryViewer directoryViewer;directoryViewer.show();return app.exec();
}

Color Names

这个实例显示了如何使用 QsortFilterProxyModel。和其他预定义模型不同,这个模型封装了一个已经存在的模型并且对在底层模型和视图之间的传递的数据进行操作。在我们的实例中,底层模型是一个由Qt所认识的颜色名称[通过调用 QColor::colorNames()得到]初始化的 QStringListModel。用户可以在 QLineEdit 中输人一个过滤器宇符串并且使用组合框指定这个字符串被如何解释(作为正则表达式、通配符模式或者固定字符串)。

ColorNamesDialog.h

#ifndef COLORNAMESDIALOG_H
#define COLORNAMESDIALOG_H#include <QDialog>class QComboBox;
class QLabel;
class QLineEdit;
class QListView;
class QSortFilterProxyModel;
class QStringListModel;class ColorNamesDialog : public QDialog
{Q_OBJECTpublic:ColorNamesDialog(QWidget *parent = 0);private slots:void reapplyFilter();private:QStringListModel      *sourceModel;QSortFilterProxyModel *proxyModel;QListView *listView;QLabel    *filterLabel;QLabel    *syntaxLabel;QLineEdit *filterLineEdit;QComboBox *syntaxComboBox;
};#endif

ColorNamesDialog.cpp

#include <QtGui>#include "colornamesdialog.h"ColorNamesDialog::ColorNamesDialog(QWidget *parent): QDialog(parent)
{sourceModel = new QStringListModel(this);sourceModel->setStringList(QColor::colorNames());proxyModel = new QSortFilterProxyModel(this);proxyModel->setSourceModel(sourceModel);proxyModel->setFilterKeyColumn(0);listView = new QListView;listView->setModel(proxyModel);listView->setEditTriggers(QAbstractItemView::NoEditTriggers);filterLabel = new QLabel(tr("&Filter:"));filterLineEdit = new QLineEdit;filterLabel->setBuddy(filterLineEdit);syntaxLabel = new QLabel(tr("&Pattern syntax:"));syntaxComboBox = new QComboBox;syntaxComboBox->addItem(tr("Regular expression"), QRegExp::RegExp);syntaxComboBox->addItem(tr("Wildcard"), QRegExp::Wildcard);syntaxComboBox->addItem(tr("Fixed string"), QRegExp::FixedString);syntaxLabel->setBuddy(syntaxComboBox);connect(filterLineEdit, SIGNAL(textChanged(const QString &)),this, SLOT(reapplyFilter()));connect(syntaxComboBox, SIGNAL(currentIndexChanged(int)),this, SLOT(reapplyFilter()));QGridLayout *mainLayout = new QGridLayout;mainLayout->addWidget(listView, 0, 0, 1, 2);mainLayout->addWidget(filterLabel, 1, 0);mainLayout->addWidget(filterLineEdit, 1, 1);mainLayout->addWidget(syntaxLabel, 2, 0);mainLayout->addWidget(syntaxComboBox, 2, 1);setLayout(mainLayout);setWindowTitle(tr("Color Names"));
}void ColorNamesDialog::reapplyFilter()
{QRegExp::PatternSyntax syntax =QRegExp::PatternSyntax(syntaxComboBox->itemData(syntaxComboBox->currentIndex()).toInt());QRegExp regExp(filterLineEdit->text(), Qt::CaseInsensitive, syntax);proxyModel->setFilterRegExp(regExp);
}

ColorNamesDialog()
我们使用常规的方式创建并且组装这个 QStringListModel。接下来就是对 QSortFilterProxyModel的构造。我们使用setSourceModel() 传递底层模型并且告诉这个代理过滤器被应用在初始模型的第0列。QComboBox::addItem()函数接受一个类型为 QVariant 的可选"数据"参数。我们使用它存储和每一个项文本对应的 QRegExp::PattemSyntax值。

reapplyFilter()
只要用户改变过滤器字符串或者模式语法组合框,就会调用这个 reapplyFilter()槽。我们使用行编辑器中的文本创建一个 QRegExp,然后设置它的模式语法为保存在组合框中当前项中保存的值。当调用 setFilterRegExp() 时,会激活新的过滤器并且会自动更新视图。

main.cpp

#include <QApplication>#include "colornamesdialog.h"int main(int argc, char *argv[])
{QApplication app(argc, argv);ColorNamesDialog dialog;dialog.show();return app.exec();
}

Qt4_使用预定义模型相关推荐

  1. TVM部署预定义模型

    TVM部署预定义模型 本文通过深度学习框架量化的模型加载到TVM中.预量化的模型导入是在TVM中提供的量化支持之一. 本文演示如何加载和运行由PyTorch,MXNet和TFLite量化的模型.加载后 ...

  2. (三)使用预定义模型QDirModel的例子

    目录: (一) Qt Model/View 的简单说明 .预定义模型 (二)使用预定义模型 QstringListModel例子 (三)使用预定义模型QDirModel的例子 (四)Qt实现自定义模型 ...

  3. (二)使用预定义模型 QStringListModel例子

    目录: (一) Qt Model/View 的简单说明 .预定义模型 (二)使用预定义模型 QstringListModel例子 (三)使用预定义模型QDirModel的例子 (四)Qt实现自定义模型 ...

  4. tensorflow预定义经典卷积神经网络和数据集tf.keras.applications

    自己开发了一个股票软件,功能很强大,需要的点击下面的链接获取: https://www.cnblogs.com/bclshuai/p/11380657.html 1.1  tensorflow预定义经 ...

  5. Predefined Shader preprocessor macros //预定义的着色器预处理宏

    Predefined Shader preprocessor macros 预定义的着色器预处理宏 Unity defines several preprocessor macros when com ...

  6. CAN笔记(17) 预定义报文ID

    CAN笔记(17) 预定义报文 ID 1. 预定义报文 2. 网络管理与特殊协议报文ID 3. 过程数据对象和服务数据对象的报文ID 1. 预定义报文 在 CANOpen 创立之初 即使在 CAN 总 ...

  7. 【Matlab】系统预定义变量——元胞数组与结构体

    [Matlab]系统预定义变量--元胞数组与结构体 往期回顾 前言 正文 一.元胞数组 1. 元胞数组操作函数 2. 代码实例 二.结构体 1. 结构体操作函数 2. 代码实例 总结 参考文献 往期回 ...

  8. 【SWAT】SWAT中预定义河网及流域

    Strahler分级 Strahler编码或Strahler数,可以用于描述河流的等级和流量,以及其他树状结构的分支等级. 对子流域进行编号的方法可以概括为以下几个步骤: 从流域出口开始,将其编号为1 ...

  9. Silverlight 预定义颜色速查表

    预定义颜色 可以使用 SolidColorBrush 绘制,它使用预定义纯色.这可以是 Colors 的静态属性 (Property) 名称,也可以是指定为 XAML 属性 (Attribute) 值 ...

最新文章

  1. layui 常用的css,使用layui xtree插件最基础样式
  2. matplotlib画图、如何提高图像分辨率?
  3. H5学习系列之Communication API
  4. Tensorflow图像通道合并,IndexError: too many indices for array
  5. vb计算机水平考试笔试,2014计算机考试二级VB笔试答题技巧汇总
  6. 测试core :: demangled_name
  7. android解析ip地址,android – 如何从IP地址解析网络主机名
  8. 并不对劲的bzoj2038:p1494:[国家集训队]小Z的袜子
  9. JPDA Java调试标准
  10. css网页布局兼容性有哪些要点与诀窍
  11. ajaxFileUpload plugin上传文件 chrome、Firefox中出现SyntaxE
  12. 【WPF】如何获取命令行参数
  13. deepin linux 安装packet tracer 7.0
  14. thymeleaf模板的应用
  15. 通用后台管理系统(1)-数据库设计
  16. 虚拟现实计算机理论文献,虚拟现实在计算机教学中的应用研究
  17. 服务器本地系统:网络受限,电脑本地连接受限制怎么办,教您解决电脑本地连接受限制...
  18. Ubuntu下rar带密码压缩/解压命令
  19. 两路VL53L0X激光测距传感器的使用
  20. 字节跳动智力题-推理题

热门文章

  1. Java-ReentrantLock-NonfairSync/FairSync
  2. SpringSecurity-1-UserDetails接口
  3. Java-虚拟机-常量池的表现方式
  4. html xpath java_Java根据XPath提取HTML
  5. @column注解_SpringBoot 注解方式快速整合Mybatis
  6. 用 rust 写算法
  7. easyui validatebox设置默认值时 去掉校验
  8. 用haslib给字符加密
  9. 20172319 《程序设计与数据结构》实验一报告
  10. 云计算学习(5-1)云平台产品介绍-华为的FusionCloud产品