(43)原理概述:
++以下是源码支持:
typedef QList<QObject*> QObjectList;
class QObject
{ public:
explicit QObject(QObject * parent = nullptr);
inline const QObjectList & children() const
{ return d_ptr->children; }
}
(44)函 children(),返回一个窗体对象的包含的所有的孩子,源代码定义在上面:
++举例:
(45)函数 findChind( ) ,查找符合要求的一个子控件,及其源码:
++ 给出其源码:
class QObject
{
public:
template<typename T> // 可见这是一个模板成员函数, T 是子对象的类型
inline T findChild( const QString & aName = QString(), //形参换行
Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{ //可见,扒掉了类型 T 里的指针与 const、volitile 修饰符,只剩下纯粹的类型属性
typedef typename std::remove_cv< // 这里是定义了新类型 ObjType
typename std::remove_pointer<T>::type
>::type ObjType;
return static_cast<T>( // 但是本函数的返回值又返回的是与 T 相同的类型
qt_qFindChild_helper(this, aName, ObjType::staticMetaObject, options)
);
}
}
(46)上面的函数里出现了枚举量,多了解下枚举类 Qt :: FindChildOptions ,此类指明了查找容器的子对象时,是否使用递归策略:
QT_BEGIN_NAMESPACE
template<typename Enum>
class QFlags //简化版:该类完成了 QT 里的枚举量的各种运算
{
private: Int i;
public :
constexpr inline QFlags() noexcept : i(0) {} //构造函数
constexpr inline Q_IMPLICIT QFlags(Enum flags) noexcept
: i(Int(flags)) {}
constexpr inline Q_IMPLICIT QFlags(QFlag flag) noexcept
: i(flag) {}
constexpr inline QFlags &operator&=(int mask) noexcept
{ i &= mask; return *this; }
constexpr inline QFlags &operator|=(QFlags other) noexcept
{ i |= other.i; return *this; }
constexpr inline operator Int() const noexcept
{ return i; }
constexpr inline QFlags operator|(QFlags other) const noexcept
{ return QFlags(QFlag(i | other.i)); }
constexpr inline QFlags operator^(QFlags other) const noexcept
{ return QFlags(QFlag(i ^ other.i)); }
void operator+(QFlags other) const noexcept = delete;
void operator-(QFlags other) const noexcept = delete;
constexpr inline bool operator!() const noexcept
{ return !i; }
friend constexpr inline //定义了友元函数
bool operator==(QFlags lhs, QFlags rhs) noexcept
{ return lhs.i == rhs.i; }
friend constexpr inline
bool operator!=(QFlags lhs, QFlags rhs) noexcept
{ return lhs.i != rhs.i; }
};
#ifndef Q_MOC_RUN
#define Q_DECLARE_FLAGS(Flags, Enum)\
typedef QFlags<Enum> Flags;
//可见,最终宏定义替换成了类型定义,生成了 QFlags<T> 的实例化类
#endif
QT_END_NAMESPACE
//上下来自于不同文件
namespace Qt // 关于 宏 Q_DECLARE_FLAGS 的解释在上面
{
enum FindChildOption {
FindDirectChildrenOnly = 0x0,
FindChildrenRecursively = 0x1 //递归查找容器中子对象
};
Q_DECLARE_FLAGS(FindChildOptions, FindChildOption)
//源码表示 FindChildOptions = QFlags<FindChildOption>
}
(47)函数 fingChildren ( ) ,查找符合要求的某一类型的多个子控件 :
++ 给出其源码支持:
class QObject
{
public:
template<typename T> //模板参数 T 指明了要查找的控件类型,也支持控件名查找
inline QList<T> findChildren(const QString &aName = QString(),
Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{
typedef typename std::remove_cv< // 简化模板参数里的 T 类型
typename std::remove_pointer<T>::type
>::type ObjType;
QList<T> list; //定义返回值类型,表明返回的是一个列表
qt_qFindChildren_helper(this, aName, ObjType::staticMetaObject,
reinterpret_cast<QList<void *> *>(&list), options);
return list;
}
#if QT_CONFIG(regularexpression) //似乎是允许使用正则表达式时定义与编译下面的重载函数
template<typename T>
inline QList<T> findChildren(const QRegularExpression &re,
Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{
typedef typename std::remove_cv<
typename std::remove_pointer<T>::type
>::type ObjType;
QList<T> list;
qt_qFindChildren_helper(this, re, ObjType::staticMetaObject,
reinterpret_cast<QList<void *> *>(&list), options);
return list;
}
#endif // QT_CONFIG(regularexpression)
}
(48)
谢谢