Qt 学习
Qt 学习
C++ 模版
QObject 提供一个十分有用的 api,T findChild(QString, Qt::FindChildOptions),这个函数接收一个模版参数,返回模版参数的类型(如果子对象可以造型成 T ),也就是说返回值已经做了 cast 造型处理,这样就可以直接用特定的子类指针接收,使用起来非常方便。可以在对象的子类中寻找特定名称(objectName)的对象,而 Qt::FindChildOptions 参数用于设置搜索范围,Qt::FindDirectChildrenOnly 可以设置搜索范围仅限于当前对象的 children,并且不迭代 children 搜索,默认选项 Qt::FindChildrenRecursively 将迭代搜索所有子对象。
以下内容摘自官方示例:
// 返回最匹配的对象指针,该对象指针可以造型成 QPushButton 指针,并且该对象的 objectName 为 button1
QPushButton *button = parentWidget->findChild<QPushButton *>("button1");
// 返回最匹配的对象指针,该对象指针可以造型成 QListWidget 指针
QPushButton *list = parentWidget->findChild<QListWidget *>();
// 返回最匹配的对象指针,仅在 parentWidget 对象的直接子对象中查找,
// 该对象指针可以造型成 QPushButton 指针,并且该对象的 objectName 为 button1
QPushButton *button = parentWidget->findChild<QPushButton *>("button1", Qt::FindDirectChildrenOnly);
// 返回最匹配的对象指针,仅在 parentWidget 对象的直接子对象中查找,
// 该对象指针可以造型成 QPushButton 指针
QListWidget *list = parentWidget->findChild<QListWidget *>(QString(), Qt::FindDirectChildrenOnly);
需要注意的是最后一种用法,这里想要在 parentWidget 中找到可造型成 QListWidget 的直接子对象,但是不需要指定对象名,第一个参数需要用 QString() 而不能用空字符串 "",否则便没有符合要求的子类 list,此时 list 的值为 0x0,结果一直找不到子对象。
以下代码为 Qt5.7 版本源代码:
// QObject.h
template<typename T>
inline T findChild(const QString &aName = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{
typedef typename QtPrivate::remove_cv<typename QtPrivate::remove_pointer<T>::type>::type ObjType;
return static_cast<T>(qt_qFindChild_helper(this, aName, ObjType::staticMetaObject, options));
}
// QObject.cpp
QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options)
{
if (!parent)
return 0;
const QObjectList &children = parent->children();
QObject *obj;
int i;
for (i = 0; i < children.size(); ++i) {
obj = children.at(i);
if (mo.cast(obj) && (name.isNull() || obj->objectName() == name))
return obj;
}
if (options & Qt::FindChildrenRecursively) {
for (i = 0; i < children.size(); ++i) {
obj = qt_qFindChild_helper(children.at(i), name, mo, options);
if (obj)
return obj;
}
}
return 0;
}
需要注意,类模版中成员函数的定义和声明都要放在 .h 文件中,防止编译器报错,参考上面的 findChild 模版成员函数,这个函数用到模版,声明和定义都放在 QObject.h 中。
该函数的实现是通过 qt_qFindChild_helper 助手函数实现的。
在 QObject.cpp 源代码中找到的两个函数定义:
void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re,const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options);QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options);
在源代码实现中,判断能否返回对象指针的判断条件是 mo.cast(obj) && (name.isNull() || obj->objectName() == name) 如果传入的名称参数是空字符串 "" 那么 name.isNull() 返回的是 false,
obj->objectName() == name 返回的是 false,整个判断返回 false,也就无法找到符合要求的子对象了。
Model/View 架构
关于 Qt 的 Model/View 架构,在 官方文档 中已经给出了详细的介绍。
实际项目中使用到的模型是 Table 模型,在子类化 QAbstractTableModel 时,重写其中一些函数用于显示数据。
比如重写 QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; 用于显示标题数据。标题数据有纵向和横向两种选择,Qt::Orientation 用于设置方向。如果不指定方向,对所有 role 值为 Qt::DisplayRole 的数据进行绘制,将会看到横向的第一个标题头似乎总是不显示或者显示的是错误的数据。原因在于 TableModel 还会显示纵向的标题头,导致两个方向的标题头重叠。
role 值有 Qt 提供的一些值如 Qt::DisplayRole,Qt::BackgroundRole,前者用于显示文本或图片,或者可以用来设置背景。
最开始接触 Qt 的 Model/View 架构时感觉它有些复杂,除了 Model 外,在重写函数时经常看到对 ModelIndex 的使用,ModelIndex 就是索引,包含一些数据,但是 QModelIndex 隐藏了它的构造函数(它的构造函数是用 private 修饰的),无法通过构造函数直接构造一个 QModelIndex 对象(需要通过 createIndex 方法构造):
以下为 Qt5.7 的部分源代码
// qabstractitemmodel.h
friend class QAbstractItemModel;
...
private:
inline QModelIndex(int arow, int acolumn, void *ptr, const QAbstractItemModel *amodel) Q_DECL_NOTHROW
: r(arow), c(acolumn), i(reinterpret_cast<quintptr>(ptr)), m(amodel) {}
编写自己的 model 类时感觉无从下手,好在官方的示例很多,介绍的也很详细。而在重写 TableModel 时,其实也没有怎么使用成员函数中 QModelIndex 参数,就是直接跳过这个参数,对外提供数据。
模型比较简单,目前仅在刷新数据时用到 QModelIndex 。
Qt 学习的更多相关文章
- QT学习第1天
QT学习第一天 坚持住!! 一 Qt概述 1.Qt发展历史 (1)1991年诞生(Haavard Nord/Eirik Chambe-Eng), (2)1994年创立Troll Tech(奇趣科技) ...
- 【转载】分享一些Qt学习资源,欢迎下载
资源来源:http://bbs.csdn.net/topics/390358737 经过我一翻整理,把一些我收集到的Qt学习资源分享给大家,主要适合新手,老鸟可以直接忽略我.要说明一下,很多资源都是在 ...
- QT学习之路--创建一个对话框
Q_OBJECT:这是一个宏,凡是定义信号槽的类都必须声明这个宏. 函数tr()全名是QObject::tr(),被他处理过的字符串可以使用工具提取出来翻译成其他语言,也就是做国际化使用. 对于QT学 ...
- 转载: Qt 学习之路 2归档
Qt 学习之路 2归档 http://www.devbean.net/2012/08/qt-study-road-2-catelog/
- Qt 学习资料
Qter开源社区http://www.qter.org/ [Qt教程], 作者yafeilinux [视频] QT学习之路:从入门到精通 <C++ Qt 编程视频教程>
- qt学习笔记(五) QGraphicsPixmapItem与QGraphicsScene的编程实例 图标拖动渐变效果
应大家的要求,还是把完整的project文件贴出来,大家省点事:http://www.kuaipan.cn/file/id_48923272389086450.htm 先看看执行效果,我用的群创7寸屏 ...
- Qt学习博客推荐
附录C Qt资源 C.1 Qt 官方资源 全 球各大公司以及独立开发人员每天都在加入 Qt 的开发社区.他们已经认识到了Qt 的架构本身便可加快应用程序开发进度.这些开发人员,无论是想开发单平台软件. ...
- qt学习教程1.qt开发环境搭建
qt学习教程1.qt开发环境搭建 首先下载qt 下载地址:http://download.qt.io/archive/qt/ 此教程使用的版本为5.1.1 下载好后,打开安装包,然后点下一步 选择一个 ...
- QT学习教程
原地址:http://www.devbean.NET/2012/08/qt-study-road-2-catelog/ 网上看到的不错的教程 本教程以qt5为主,部分地方会涉及qt4.据说非常适合qt ...
- Qt学习之路
Qt学习之路_14(简易音乐播放器) Qt学习之路_13(简易俄罗斯方块) Qt学习之路_12(简易数据管理系统) Qt学习之路_11(简易多文档编辑器) Qt学习之路_10(Qt ...
随机推荐
- Kinect插件使用
Kinect Scripts文件夹下所有managers(管理器)的用途: 这些在KinectScripts文件夹下的管理器都是组件,你可以根据你想实现的功能在项目中使用它. KinectManage ...
- c# 时间格式处理,获取格式: 2014-04-12T12:30:30+08:00
C# 时间格式处理,获取格式: 2014-04-12T12:30:30+08:00 一.获取格式: 2014-04-12T12:30:30+08:00 方案一:(局限性,当不是当前时间时不能使用) ...
- Google准实时数据仓库Mesa(一)
本文来自网易云社区 作者:王潘安 以下是本人在学习Google的Mesa数据仓库论文的记录,翻译出来给大家分享,翻译水平有限,请多多包涵.因论文比较长,本人将论文按照Mesa不同的模块分开翻译,方便阅 ...
- Gazebo学习随记4 Actor: 该配合你的演出我视而不见
在Gazebo仿真中,除了模型model外,还有一种和model并列的类型——actor. 相比于model受物理引擎的作用,actor不受重力等等的影响,可以按照设定的运动轨迹进行运动. <s ...
- CentOS6.5上Zabbix3.0的RPM安装【三】-安装并添加Agent
七.Download and install Zabbix Agent Zabbix Agent is required to install on all remote systems needs ...
- django 基础框架学习 (三)
Django框架基础-03数据库新增数据 1.save⽅法 >>> from datetime import date >>> f ...
- 最短路【bzoj1726】: [Usaco2006 Nov]Roadblocks第二短路
1726: [Usaco2006 Nov]Roadblocks第二短路 Description 贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友.贝茜很喜欢路边的风景,不想那么快地结束她 ...
- luogu1556 幸福的路
注意到\(n\le10\),所以枚举经过的拐弯牛的所有排列. 注意到STL是一个好东西,所以我这里偷懒直接使用了next_permutation 枚举所有n的排列,对于每一个排列也就是经过拐弯牛的顺序 ...
- 选课 ( dp 树形dp 动态规划 树规)
和某篇随笔重了?!!?!?!?!?!?不管了留着吧 题目: 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之 ...
- POJ1063 Flip and Shift
题目来源:http://poj.org/problem?id=1063 题目大意: 有一种游戏如图所示.一个填满黑白球的转盘,它可以有两种操作,一种是将大转盘顺时针旋转,所有球的位置顺时针挪一位,另一 ...