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 ...
随机推荐
- android studio中Fragment使用webview返回上一页的问题
在Fragment中使用了腾讯的X5 webview,虽然好用,但是在Fragment中传递消息困难,想要返回上一页,还得各种消息传递什么的,麻烦.可是在Fragment中又不能使用onKeyDown ...
- linux 进程间通信机制(IPC机制)一总览
1.作用:进程间通信机制(Inter Process Communication,IPC),这些IPC机制的存在使UNIX在进程通信领域手段相当丰富,也使得程序员在开发一个由多个进程协作的任务组成的系 ...
- [SinGuLaRiTy] (树形)数据结构题目复习
[SinGuLaRiTy-1023] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 普通平衡树 题目描述 你需要写一种数据结构(可参考题目标 ...
- Python 文件和异常
一.从文件中读取数据 #!/usr/bin/env python with open('pi') as file_object: contents = file_object.read() print ...
- Linux errno错误对照表
errno 在 <errno.h> 中定义,错误 Exx 的宏定义在 /usr/include/asm-generic 文件夹下面的 errno-base.h 和 errno.h,分别定 ...
- DB2安装步骤
##################################DB2的安装########################### ## 安装前准备 ## 关闭内存地址随机化机制 vi /etc/ ...
- 树的遍历顺序 - dfs序|欧拉序|dfn序(备忘)
(仅作备忘) dfs序是dfs过程中对于某节点进入这个节点的子树和离开子树的顺序 满足每个节点都会在dfs序上出现恰好两次 任意子树的dfs序都是连续的 欧拉序是dfs过程中经过节点的顺序 每个节点至 ...
- zabbix监控tcp连接数的脚本!!
#!/bin/bash #this script is used to get tcp and udp connetion status #tcp status metric=$ tmp_file=/ ...
- Common Subsequence(最长公共子序列)
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. ...
- Educational Codeforces Round 3 C
C. Load Balancing time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...