最近有涉及到通过QT做界面的事情,原来对java spring 有一些了解,就想通过配置文件来动态创建类对象,所以就得研究下QT的反射。一下是QWidget的反射的实现
class ObjectWidgetFactory
{
public:
template<typename T>
static void registerClass()
{
constructors().insert(T::staticMetaObject.className(), &constructorHelper<T>); //插入函数指针用
}
static QWidget* createObject(const QString& className, QWidget* parent = NULL) //根据名字获取函数指针进行创建
{
Constructor constructor = constructors().value(className);
if (constructor == NULL)
return NULL;
return (*constructor)(parent);
}
private:
typedef QWidget* (*Constructor)(QWidget* parent); //函数指针的定义
template<typename T>
static QWidget* constructorHelper(QWidget* parent)
{
return new T(parent);
}
static QHash<QString, Constructor>& constructors()
{
static QHash<QString, Constructor> instance;
return instance;
}
};
///下面是类模版的实现,解决不同基类的反射创建
template<class classT>
class ObjectWidgetFactory
{
public:
template<typename T>
static void registerClass()
{
constructors().insert(T::staticMetaObject.className(), &constructorHelper<T>); //插入函数指针用
}
static classT* createObject(const QString& className, classT* parent = NULL) //根据名字获取函数指针进行创建
{
Constructor constructor = constructors().value(className);
if (constructor == NULL)
return NULL;
return (*constructor)(parent);
}
private:
typedef classT* (*Constructor)(classT* parent); //函数指针的定义
template<typename T>
static classT* constructorHelper(classT* parent)
{
return new T(parent);
}
static QHash<QString, Constructor>& constructors()
{
static QHash<QString, Constructor> instance;
return instance;
}
};
使用举例:
ObjectWidgetFactory::registerClass<QMenuBar>();
ObjectWidgetFactory::registerClass<QToolBar>(); //先注册上
auto eleTab = ObjectWidgetFactory::createObject(eleMenu.attributeNode("class").value()); // 动态创建
//eleMenu.attributeNode("class").value() 在XML 解析到对应需要创建的类名
单利宏实现代码:
#define IMPLEMENTION_SINGLETON_CLASS( Type ) \
public: \
static Type& GetInstance() \
{ \
static Type oInstance; \
return oInstance; \
} \
private: \
Type( const Type& ) \
{ \
} \
\
Type& operator= ( const Type& ) \
{ \
return *this; \
}
使用举例:
class DemoWidget : public QDockWidget
{
public:
DemoWidget() = default;
QDockWidget* creatDemo();
};
class LeftSidebarFactory
{
IMPLEMENTION_SINGLETON_CLASS(LeftSidebarFactory)
private:
LeftSidebarFactory() = default;
public:
QDockWidget* GetViewToName(QString name);
};
//简单工厂和单利模式使用