使用项视图的简便类

使用。的项视图中那些方便的子类通常要比定义一个自定义模型简单得多,并且姐果我们不需
要由区分模型和视图所带来的好处时,这种方法也是比较合适的。

Flowchart Symbol Picker

演示了一个只读的QListWidget。先从一个允许用户在列表中选择流程图符号的简单对话框开始。每个项都由一个图标、一段文本和一个唯一的ID组成。

FlowChartSymbolPicker.h

#ifndef FLOWCHARTSYMBOLPICKER_H
#define FLOWCHARTSYMBOLPICKER_H#include <QDialog>
#include <QMap>class QDialogButtonBox;
class QIcon;
class QListWidget;class FlowChartSymbolPicker : public QDialog
{Q_OBJECTpublic:FlowChartSymbolPicker(const QMap<int, QString> &symbolMap,QWidget *parent = 0);int selectedId() const { return id; }void done(int result);private:QIcon iconForSymbol(const QString &symbolName);QListWidget *listWidget;QDialogButtonBox *buttonBox;int id;
};#endif

当构造这个对话框时,我们必须给它传递一个QMap<int, QString>,在它运行之后,可以通过调用selectedId()获得一个选中的ID(或者如果用户没有选中任何一项,就返回-1)。

FlowChartSymbolPicker.cpp

#include <QtGui>#include "flowchartsymbolpicker.h"FlowChartSymbolPicker::FlowChartSymbolPicker(const QMap<int, QString> &symbolMap, QWidget *parent): QDialog(parent)
{id = -1;listWidget = new QListWidget;listWidget->setIconSize(QSize(60, 60));QMapIterator<int, QString> i(symbolMap);while (i.hasNext()) {i.next();QListWidgetItem *item = new QListWidgetItem(i.value(), listWidget);item->setIcon(iconForSymbol(i.value()));item->setData(Qt::UserRole, i.key());}buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok| QDialogButtonBox::Cancel);connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));QVBoxLayout *mainLayout = new QVBoxLayout;mainLayout->addWidget(listWidget);mainLayout->addWidget(buttonBox);setLayout(mainLayout);setWindowTitle(tr("Flowchart Symbol Picker"));
}void FlowChartSymbolPicker::done(int result)
{id = -1;if (result == QDialog::Accepted) {QListWidgetItem *item = listWidget->currentItem();if (item){id = item->data(Qt::UserRole).toInt();}}QDialog::done(result);
}QIcon FlowChartSymbolPicker::iconForSymbol(const QString &symbolName)
{QString fileName = ":/images/" + symbolName.toLower();fileName.replace(' ', '-');return QIcon(fileName);
}

FlowChartSymbolPicker
我们把id(最后被选择的ID)初始化为-1。接下来构造一个方便的项视图窗口部件QListWidget。我们遍历这个流程图符号映射中的每一个项,并且为了显示每一个项而创建一个QListWidgetItem。QListWidgetItem构造函数都会在父对象QListWidget之后获得一个代表将要显示的文本QString。

然后,设置项的图标并且调用setData()函数把任意ID保存到QListWidgetItem中。iconForSymbol()私有函数为每一个给定的符号名称返回一个QIcon。

QListWidgetItem有几个角色(role),每一个角色都有一个关联的QVariant。最常用的角色有Qt::DisplayRole、Qt::EditRole和Qt::IconRole,并且这些角色都有方便的设置和获取函数[setText()和setIcon()],另外还有其他几个角色。通过指定一个大于等于Qt::UserRole的值,就可以定义自定义的角色。在例子中,使用Qt::UserRole存储每一个项的ID。

构造函数中省略的部分包括创建按钮、对这些窗口部件进行摆放以及设置这个窗口的标题栏。

done()
这个 done() 函数是由 QDialog 重新实现的。当用户单击 OK 或者 Cancel 按钮时,就会调用它。如果用户单击 OK ,就获得相应的项并且使用 data() 函数提取 ID。如果对项的文本感兴趣,则可以通过调用 item->data(Qt::DisplayRole).toString() 或者更为方便的 item->text()来获取文本。

默认情况下, QListWidget 是只读的。如果想让用户编辑这些项,则可以使用 AbstractItemView::setEditTriggers() 设置这个视图的编辑触发器(edit trigger) 。例如,AbstractItemVjew::AnyKeyPressed 这个设置值的意思是:用户只要一开始输入就进入项的编辑状态。类似地,也可以提供一个Edit(编辑)按钮(还可以提供 Add 按钮和 Delete 按钮) ,同时使用信号-槽连接,这样就可以使用程序来控制编辑操作了。

main.cpp

#include <QApplication>#include "flowchartsymbolpicker.h"int main(int argc, char *argv[])
{QApplication app(argc, argv);QMap<int, QString> symbolMap;symbolMap.insert(132, QObject::tr("Data"));symbolMap.insert(135, QObject::tr("Decision"));symbolMap.insert(137, QObject::tr("Document"));symbolMap.insert(138, QObject::tr("Manual Input"));symbolMap.insert(139, QObject::tr("Manual Operation"));symbolMap.insert(141, QObject::tr("On Page Reference"));symbolMap.insert(142, QObject::tr("Predefined Process"));symbolMap.insert(145, QObject::tr("Preparation"));symbolMap.insert(150, QObject::tr("Printer"));symbolMap.insert(152, QObject::tr("Process"));FlowChartSymbolPicker picker(symbolMap);picker.show();return app.exec();
}

Coordinate Setter

这个例子演示一个可编辑的QTableWidget。现在已经看到了如何使用方便的项视图类来查看和选择数据,接下来将会看一个可以编辑数据的例子。再次使用一个对话框,它显示自是用户可以编辑的一对(x, y) 坐标。

CoordinateSetter.h

#ifndef COORDINATESETTER_H
#define COORDINATESETTER_H#include <QDialog>
#include <QList>
#include <QPointF>class QDialogButtonBox;
class QTableWidget;class CoordinateSetter : public QDialog
{Q_OBJECTpublic:CoordinateSetter(QList<QPointF> *coords, QWidget *parent = 0);void done(int result);private slots:void addRow();private:QTableWidget *tableWidget;QDialogButtonBox *buttonBox;QList<QPointF> *coordinates;
};#endif

CoordinateSetter.cpp

#include <QtGui>#include "coordinatesetter.h"CoordinateSetter::CoordinateSetter(QList<QPointF> *coords,QWidget *parent): QDialog(parent)
{coordinates = coords;tableWidget = new QTableWidget(0, 2);tableWidget->setHorizontalHeaderLabels(QStringList() << tr("X") << tr("Y"));for (int row = 0; row < coordinates->count(); ++row) {QPointF point = coordinates->at(row);addRow();tableWidget->item(row, 0)->setText(QString::number(point.x()));tableWidget->item(row, 1)->setText(QString::number(point.y()));}buttonBox = new QDialogButtonBox(Qt::Horizontal);QPushButton *addRowButton = buttonBox->addButton(tr("&Add Row"),QDialogButtonBox::ActionRole);buttonBox->addButton(QDialogButtonBox::Ok);buttonBox->addButton(QDialogButtonBox::Cancel);connect(addRowButton, SIGNAL(clicked()), this, SLOT(addRow()));connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));QVBoxLayout *mainLayout = new QVBoxLayout;mainLayout->addWidget(tableWidget);mainLayout->addWidget(buttonBox);setLayout(mainLayout);setWindowTitle(tr("Coordinate Setter"));
}void CoordinateSetter::done(int result)
{if (result == QDialog::Accepted) {coordinates->clear();for (int row = 0; row < tableWidget->rowCount(); ++row) {double x = tableWidget->item(row, 0)->text().toDouble();double y = tableWidget->item(row, 1)->text().toDouble();coordinates->append(QPointF(x, y));}}QDialog::done(result);
}void CoordinateSetter::addRow()
{int row = tableWidget->rowCount();tableWidget->insertRow(row);QTableWidgetItem *item0 = new QTableWidgetItem;item0->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);tableWidget->setItem(row, 0, item0);QTableWidgetItem *item1 = new QTableWidgetItem;item1->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);tableWidget->setItem(row, 1, item1);tableWidget->setCurrentItem(item0);
}

CoordinateSetter()
这个 QTableWidget 构造函数得到要在这个表格中显示的行和列的初始数字。在 QTableWidget 中的每一个项都使用一个 QTableWidgetItem 表示,包括水平方向和垂宜方向的表头项。 setHorizontalHeaderLabels ()函数则设置每一个表窗口部件的水平表头项的文本为所传递的字符串列表中的相应文本。默认情况下,QTableWidget 会提供一个垂直表头,这个列的标签从1开始,这正是我们想要的,所以不需要手工设置垂直表头的标签。

一旦创建完列标签,就可以遍历传递进来的坐标数据。对于每一个(x, y)坐标对,都添加一个新行[使用私有函数 addRow()],同时在每一行的列中设置合适的文本。

默认情况下, QTableWidget 允许编辑。用户可以在遍历一个表的时候,按下F2或者任意简单的输入,来编辑这个表的任意单元格。用户在这个视图中所做的任何修改都会自动影响这些 QTableWidgetltem。为了防止编辑,可以调用setEditTriggers(QAbstractItemView::NoEditTriggers)。

addRow()
当用户单击 Add Row 按钮时,就会调用这个 addRow()槽,这种方式在函数构造中也经常使用到。我们使用QTableWidget::insertRow() 插人一个新的行,然后创建两个 QTableWidgetItem()项,并利用 QTableWidget::insertRow()把它们添加到表中。除了该项外, QTableWidget: : setItem()还需要一行及一列。最后,我们设置当前项,这样用户就可以开始编辑新的一行的第一项了。

done()
最后,当用户单击 OK 时,就清空传递给这个对话框的坐标,并且根据这个 QTableWidget 的所有项创建一个新的坐标集。

main.cpp

#include <QtGui>#include "coordinatesetter.h"int main(int argc, char *argv[])
{QApplication app(argc, argv);QList<QPointF> coordinates;coordinates << QPointF(0.0, 0.9)<< QPointF(0.2, 11.0)<< QPointF(0.4, 15.4)<< QPointF(0.6, 12.9)<< QPointF(0.8, 8.5)<< QPointF(1.0, 7.1)<< QPointF(1.2, 4.0)<< QPointF(1.4, 13.6)<< QPointF(1.6, 22.2)<< QPointF(1.8, 22.2);CoordinateSetter coordinateSetter(&coordinates);coordinateSetter.show();return app.exec();
}

Settings Viewer

这个例子演示了一个只读的QTreeWidget。我们将会查看一些应用程序的代码片段,它使用 QTreeWidget 显示 Qt 应用程序设置。 QTreeWidget 默认是只读的。

SettingsViewer.h

#ifndef SETTINGSVIEWER_H
#define SETTINGSVIEWER_H#include <QDialog>class QDialogButtonBox;
class QSettings;
class QTreeWidget;
class QTreeWidgetItem;class SettingsViewer : public QDialog
{Q_OBJECTpublic:SettingsViewer(QWidget *parent = 0);private slots:void open();private:void readSettings();void addChildSettings(QSettings &settings, QTreeWidgetItem *item,const QString &group);QTreeWidget *treeWidget;QDialogButtonBox *buttonBox;QString organization;QString application;
};#endif

SettingsViewer.cpp

#include <QtGui>#include "settingsviewer.h"SettingsViewer::SettingsViewer(QWidget *parent): QDialog(parent)
{organization = "Trolltech";application = "Designer";treeWidget = new QTreeWidget;treeWidget->setColumnCount(2);treeWidget->setHeaderLabels(QStringList() << tr("Key") << tr("Value"));treeWidget->header()->setResizeMode(0, QHeaderView::Stretch); // 列宽,固定treeWidget->header()->setResizeMode(1, QHeaderView::Stretch);buttonBox = new QDialogButtonBox(QDialogButtonBox::Open| QDialogButtonBox::Close);connect(buttonBox, SIGNAL(accepted()), this, SLOT(open()));connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));QVBoxLayout *mainLayout = new QVBoxLayout;mainLayout->addWidget(treeWidget);mainLayout->addWidget(buttonBox);setLayout(mainLayout);setWindowTitle(tr("Settings Viewer"));readSettings();
}void SettingsViewer::open()
{QDialog dialog(this);QLabel *orgLabel = new QLabel(tr("&Organization:"));QLineEdit *orgLineEdit = new QLineEdit(organization);orgLabel->setBuddy(orgLineEdit);QLabel *appLabel = new QLabel(tr("&Application:"));QLineEdit *appLineEdit = new QLineEdit(application);appLabel->setBuddy(appLineEdit);QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);connect(buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));connect(buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));QGridLayout *gridLayout = new QGridLayout;gridLayout->addWidget(orgLabel, 0, 0);gridLayout->addWidget(orgLineEdit, 0, 1);gridLayout->addWidget(appLabel, 1, 0);gridLayout->addWidget(appLineEdit, 1, 1);QVBoxLayout *mainLayout = new QVBoxLayout;mainLayout->addLayout(gridLayout);mainLayout->addWidget(buttonBox);dialog.setLayout(mainLayout);dialog.setWindowTitle(tr("Choose Settings"));if (dialog.exec()) {organization = orgLineEdit->text();application = appLineEdit->text();readSettings();}
}void SettingsViewer::readSettings()
{QSettings settings(organization, application);treeWidget->clear();addChildSettings(settings, 0, "");treeWidget->sortByColumn(0);treeWidget->setFocus();setWindowTitle(tr("Settings Viewer - %1 by %2").arg(application).arg(organization));
}void SettingsViewer::addChildSettings(QSettings &settings,QTreeWidgetItem *parent, const QString &group)
{if (!parent)parent = treeWidget->invisibleRootItem();QTreeWidgetItem *item;settings.beginGroup(group);foreach (QString key, settings.childKeys()) {item = new QTreeWidgetItem(parent);item->setText(0, key);item->setText(1, settings.value(key).toString());}foreach (QString group, settings.childGroups()) {item = new QTreeWidgetItem(parent);item->setText(0, group);addChildSettings(settings, item, group);}settings.endGroup();
}

SettingsViewer()
为了访问应用程序的设置,必须使用组织名称和应用程序名称作为参数创建 QSettings 对象。我们设置了默认的名称(Trolltech的Designer),然后构造一个新的QTreeWidget。树形窗口部件的头视图控制了树形列队的大小。我们设置两列的重定义模式为 Stretch。这就告诉了头视图总是确保列能够填充有用的空间。在这种模式下,用户或者程序都不能重新调整列的大小。在构造函数的最后,我们调用这个 readSetting()函数来构成树形窗口部件。

readSettings()
应用程序的设置会存储在一个由键和值组成的分层结构中。 addChildSettings()私有函数需要一个设置对象、一个父对象的 QTreeWidgetItem 和当前"组" (group) 。QSettings群组相当于文件系统目录。 addChildSettings()函数可以递归调用自己来遍历任意一个树状结构。readSettings() 里是初始
调用,并且传递一个作为父项的空指针,表示这是根。

addChildSettings()
addChildSettings() 函数用于创建所有的 QTreeWidgetItem。它在设置树的当前层次中遍历所有键并且为每个键创建一个 QTableWidgetItem。如果空指针被作为 parent 项传递进来,就创建一个以QTreeWidget::invisibleRootItem()为父对象的项,这样它就成为了顶层项。第一列设置为键的名称,第二列设置为相对应的值。

接下来,这个函数在当前层中遍历每一个组。对于每一个组,都会创建一个新的 QTreeWidgetItem ,并且把它的第一列设置为这个组的名称。然后这个函数会把这个群组项作为父对象递归调用自己,这样就可以用这个组的子项来构成这个 QTreeWidget 了。

main.cpp

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

Qt4_使用项视图的简便类相关推荐

  1. 一劳永逸,iOS 网页视图控制器通用类封装

    原文链接:http://www.jianshu.com/p/553424763585 随着 H5 的发展,在 iOS 开发中,网页视图的使用率逐渐提升,为了增加代码封装度.减轻开发负担,因此通常会对网 ...

  2. Qt 项目视图的便捷类

    Qt 项目视图的便捷类 Qt中提供了一些标准部件来提供经典的基于项的容器部件,它们的底层是通过模型.视图框架实现的. 这些部件分别是QListWidget.QTreeWidget.QTableWidg ...

  3. mysql jpa 批注 视图_通过JPA注解映射视图的实体类 jpa 视图 无主键 @Query注解的用法(Spring Data JPA) jpa 使用sql语句...

    参考: https://blog.csdn.net/qq465235530/article/details/68064074 https://www.cnblogs.com/zj0208/p/6008 ...

  4. CodeSmith生成SQL Server视图的实体类脚本/对应的生成模板

    C#生成sql视图的实体类 using System; using System.Text; using CodeSmith.Engine; using SchemaExplorer; using S ...

  5. Boost:测试使用大小为0的类array <>特化

    Boost:测试使用大小为0的类array <>特化 实现功能 C++实现代码 实现功能 测试使用大小为0的类array <>特化 C++实现代码 #include <s ...

  6. 【苹果推iMessage送】摆设overrideUserInterfaceStyle属性以使该视图及其子视图具备特定的UIUserInterfaceStyle

    推荐内容IMESSGAE相关 作者推荐内容 iMessage苹果推软件 *** 点击即可查看作者要求内容信息 作者推荐内容 1.家庭推内容 *** 点击即可查看作者要求内容信息 作者推荐内容 2.相册 ...

  7. SpringMVC几个核心类(控制器核心类,加载配置文件核心类,处理url影射核心类,处理视图资源核心类,方法动态调用核心类)

    核心类 制器核心类: •org.springframework.web.servlet.DispatcherServlet  - 配置web.xml   加载配置文件核心类: •org.springf ...

  8. Win10任务栏程序设置显示最近使用项

    最近使用项用途 在Win10系统中,用户将程序锁定到任务栏后,若程序支持最近使用项功能,则用户在锁定程序图标上右键,即可看到最近使用项,如下图所示.有的Ghost系统可能会关闭此功能,可以通过如下方法 ...

  9. [译] 重写 loadView() 方法使 Swift 视图代码更加简洁

    原文地址:Writing Cleaner View Code in Swift By Overriding loadView() 原文作者:Bruno Rocha 译文出自:掘金翻译计划 本文永久链接 ...

最新文章

  1. 【2012天津区域赛】部分题解 hdu4431—4441
  2. 趣文:程序员/开发人员的真实生活
  3. java 面试指南_Java面试参考指南–第1部分
  4. vivado fpga最最简单的入门--led闪烁 创建工程+代码输入+添加引脚约束完整具体流程
  5. 第一步:Spring访问数据库(jdbcTemplate)
  6. python socket 接口
  7. GEE学习总结(3)——矢量面外接矩形和外包络面绘制与矢量数据导出
  8. VS2017\VS2019\VS2022项目多余文件(中间文件\临时文件)一键清理BAT
  9. java去除对象属性空格_JAVA 对象中去除空格
  10. 软件实现兼容多厂商服务器运维管理,华为eSight ICT运维系统 略述网管系统
  11. SpringBoot-引入jackson-dataformat-xml之后,本返回json的接口返回xml
  12. 滴滴秋招提前批正式开始,现在投递免笔试
  13. html背景图片的隐藏,CSS隐藏图片背景上方的文字内容
  14. SlidesJS基本使用方法和官方文档解释 【Jquery幻灯片插件 Jquery相册插件】
  15. Spatial AI
  16. FMM 大战 LMM - SOFR 企稳 Part III
  17. 【51单片机实验笔记】3. LED点阵的基本控制
  18. mac实用小技巧之解压.xip文件
  19. javascript高级程序设计阅读收获(5.4.2)——Math
  20. 网摘:WINDOWS所有系统文件的用途

热门文章

  1. Spring-ConfigurationClassParser类
  2. Linux 操作系统下常见信号详解
  3. 四个角不是直角的四边形_同步资料人教版四上数学第五单元平行四边形和梯形5.1...
  4. 智慧林业整体解决方案_智慧农贸市场整体解决方案——前期调研篇
  5. 2019春第一课程设计报告
  6. hibernate入门实例
  7. Android Studio优秀插件汇总
  8. hadoop-0.20.2完全分布式集群
  9. 修改lgoin,http://www.tuicool.com/articles/U3iyqq
  10. quartz 两次执行问题