来源:http://windrocblog.sinaapp.com/?p=799
最近做的一个Qt程序想加入一些扩展性,想让界面里的控件可以添加删除,而不需要改动程序代码。这就需要加入一些通用处理代码,基础就是可以遍历控件,或者可以按照名字(保存在字符串中)得到控件的指针。而字符串可以从外部配置文件中动态获取,不用重新编译项目。
Qt中有两种获取子控件的方式,一种是模板函数,另一种不区分类型,返回QList<QObject*>。
1. QObject::findChild
template
<
typename
T> T QObject::findChild (
const
QString & name = QString() )
const
根据name返回相应的T类型控件指针。
2. QObject::findChildren
template
<
typename
T> QList<T> QObject::findChildren (
const
QRegExp & regExp )
const
3. QObject::children
const
QObjectList & QObject::children ()
const
返回所有的子控件。
前两种方式需要知道控件的类型,而第三种方法返回的指针都是QObject,需要判断控件的具体类型才能转换成相应的控件并使用。Qt提供很好的机制来实现这个功能:Qt Meta-Object System。
QObject::metaObject()返回QMetaObject对象,利用该对象可以得到类型相关信息。
QMetaObject::className()返回对象的类型。QObject::children()得到的指针可以根据对象类型名提升为实际的子类指针。
const QObjectList list=cur_groupbox->children(); |
2 | foreach(QObject* obj,list) |
4 | QString class_name=QString::fromAscii(obj->metaObject()->className()); |
5 | if (class_name== "QCheckBox" ) |
7 | QCheckBox* cb=(QCheckBox*)obj; |
8 | QString object_name = cb->objectName(); |
9 | QString key=cur_group+ "/" +object_name.mid(QString( "cb_" +prefix).length(),-1); |
11 | QString var=ini_config_map[group_name]->value(key).toString(); |
12 | if (var==tr( "YES" ) || var==tr( "yes" )) |
16 | else if (var==tr( "NO" ) || var==tr( "no" )) |
18 | cb->setChecked( false ); |
23 | if (class_name== "QLineEdit" ) |
25 | QLineEdit* le=(QLineEdit*)obj; |
26 | QString object_name = le->objectName(); |
27 | QString key=cur_group+ "/" +object_name.mid(QString( "le_" +prefix).length(),-1); |
28 | QString var=ini_config_map[group_name]->value(key).toString(); |
上例中我只需要处理QCheckBox和QLineEdit两种的控件,当然这两种控件的处理方式有一些相近的地方,可以简化代码,但我还没什么具体的想法,跪求指导啊。