根据类名信息动态创建对象技术,可以降低代码的耦合性和复杂性,还可以实现脚本化编程,动态解析对象,提高内存利用率和程序的灵活性
直接上代码,多改改参数就玩明白了。
通过字符串,动态创建按钮(换言之,如果这个字符串是从文件里读取出来的,是不是就是动态创建界面了)
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QByteArray>
#include <QMetaObject>
#include <QHash>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#ifndef REFLECT_H
#define REFLECT_H
class Reflect
{
public:
template<typename T>
static void registerClass()
{
constructors().insert( T::staticMetaObject.className(), &constructorHelper<T> );
}
static QObject* newInstance( const QByteArray& className, QWidget* parent = nullptr )
{
Constructor constructor = constructors().value( className );
if ( constructor == nullptr )
return nullptr;
return (*constructor)( parent );
}
private:
typedef QObject* (*Constructor)( QWidget* parent );
template<typename T>
static QObject* constructorHelper( QWidget* parent )
{
return new T( parent );
}
static QHash<QByteArray, Constructor>& constructors()
{
static QHash<QByteArray, Constructor> instance;
return instance;
}
};
#endif // REFLECT_H
#endif // MAINWINDOW_H
mainwindow.cpp
我注释的那一行也可以创建成功,只不过不用转换(qstring类型与byte类型互相转换)
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QPushButton"
#include "QCheckBox"
#include "qcheckbox.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QString abc = "QPushButton";
QByteArray a = "QPushButton";
Reflect::registerClass<QPushButton>();
QPushButton* object = (QPushButton*)Reflect::newInstance(abc.toUtf8());
// QPushButton* object = (QPushButton*)Reflect::newInstance(a);
object->setGeometry(50,50,100,40);
object->setText("我是动态的");
object->setParent(this);
QPushButton* hh = new QPushButton(this);
connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(clicked()));
}
MainWindow::~MainWindow()
{
delete ui;
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
运行结果: