在做QT自定义组件开发的时候,拷贝代码,再批改太繁琐了,所以想着能不能主动生成下根底组件,于是有了主动生成组件的想法。一个根本的组件是长这个样子:
.pri QT子工程配置文件*.cpp,*.h, 组件内容*plugin.cpp,*plugin.h,组件插件化配置,次要用于qt designer里进行利落
一开始的想法是应用bat脚本(因为外面应用了中文,所以此文件须要保留为ansi格局,保留成UTF-8的化执行会有问题)批处理,运行后先拷贝cpushbutton组件目录,而后遍历此目录,对文件进行重命名
@echo offset target=DialogButtonBoxset cTarget=C%target%set qTarget=Q%target%set dir="%cd%/cpushbutton - 正本"set lowerCTarget=%cTarget%for %%i in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do call set lowerCTarget=%%lowerCTarget:%%i=%%i%%set upperCTarget=%cTarget%for %%i in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do call set upperCTarget=%%upperCTarget:%%i=%%i%%ren %dir% %lowerCTarget%set newDir="%cd%/%lowerCTarget%"for /r %newDir% %%i in (*.*) do ( if "%%~xi"==".pri" ( ren %%i "%lowerCTarget%%%~xi" )else ( echo "%%~ni"| findstr "plugin" >nul &&( ren %%i "%lowerCTarget%plugin%%~xi" )||( ren %%i "%lowerCTarget%%%~xi" ) ))
重命名后须要的是文件内容替换,整顿了一下后大略是这么些数据,为了不便,我在bat里主动生成了对应内容,在QT creator里间接拷贝过来,执行五次替换即可
echo CPUSHBUTTON-%upperCTarget% > 1.txtecho QPushButton-%qTarget% >> 1.txtecho CPushButton-%cTarget% >> 1.txtecho cpushbutton-%lowerCTarget% >> 1.txtecho cPushButton-c%target% >> 1.txt
感觉还是繁琐,就想着这五次替换能不能一部到位,惋惜的是QT creator不能间接执行定义的脚本,间接做五次替换,所以萌发了本人写个程序呗,做文件替换。
一、定义demo
demo.pri
HEADERS += $$PWD/{FILENAME}.hHEADERS += $$PWD/{FILENAME}plugin.hSOURCES += $$PWD/{FILENAME}.cppSOURCES += $$PWD/{FILENAME}plugin.cpp
demo.h
/*** @Author clarence* @Time 2022-06-28 T 14:32* @Function *** Copyright (c) 2022**/#ifndef {MACRO}_H#define {MACRO}_H#include <{PARENTCLASSNAME}>#include <QtUiPlugin/QDesignerExportWidget>class QDESIGNER_WIDGET_EXPORT {CLASSNAME} : public {PARENTCLASSNAME}{ Q_OBJECTpublic: {CLASSNAME}(QWidget *parent = 0);};#endif // {MACRO}_H
demo.cpp
/*** @Author clarence* @Time 2022-06-28 T 14:34* @Function *** Copyright (c) 2022**/#include "{FILENAME}.h"{CLASSNAME}::{CLASSNAME}(QWidget *parent) : {PARENTCLASSNAME}(parent){}
dempplugin.h
/*** @Author clarence* @Time 2022-06-28 T 14:33* @Function *** Copyright (c) 2022**/#ifndef {MACRO}PLUGIN_H#define {MACRO}PLUGIN_H#include <QDesignerCustomWidgetInterface>class {CLASSNAME}Plugin : public QObject, public QDesignerCustomWidgetInterface{ Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface)public: {CLASSNAME}Plugin(QObject *parent = nullptr); bool isContainer() const override; bool isInitialized() const override; QIcon icon() const override; QString domXml() const override; QString group() const override; QString includeFile() const override; QString name() const override; QString toolTip() const override; QString whatsThis() const override; QWidget *createWidget(QWidget *parent) override; void initialize(QDesignerFormEditorInterface *core) override;private: bool m_initialized;};#endif // {MACRO}PLUGIN_H
demoplugin.cpp
/*** @Author clarence* @Time 2022-06-28 T 14:34* @Function *** Copyright (c) 2022**/#include "{FILENAME}.h"#include "{FILENAME}plugin.h"#include <QtPlugin>{CLASSNAME}Plugin::{CLASSNAME}Plugin(QObject *parent) : QObject(parent){ m_initialized = false;}void {CLASSNAME}Plugin::initialize(QDesignerFormEditorInterface * /* core */){ if (m_initialized) return; // Add extension registrations, etc. here m_initialized = true;}bool {CLASSNAME}Plugin::isInitialized() const{ return m_initialized;}QWidget *{CLASSNAME}Plugin::createWidget(QWidget *parent){ return new {CLASSNAME}(parent);}QString {CLASSNAME}Plugin::name() const{ return QLatin1String("{SHOWNAME}");}QString {CLASSNAME}Plugin::group() const{ return QLatin1String("{GROUP}");}QIcon {CLASSNAME}Plugin::icon() const{ return QIcon(QLatin1String(""));}QString {CLASSNAME}Plugin::toolTip() const{ return QLatin1String("");}QString {CLASSNAME}Plugin::whatsThis() const{ return QLatin1String("");}bool {CLASSNAME}Plugin::isContainer() const{ return false;}QString {CLASSNAME}Plugin::domXml() const{ return QLatin1String(R"( <ui language="c++">> <widget class="{CLASSNAME}" name="{CASENAME}"/> )" R"( <customwidgets> <customwidget> <class>{CLASSNAME}</class> <header>{FILENAME}.h</header> <extends>{PARENTCLASSNAME}</extends> </customwidget> </customwidgets> ") R"( </ui> )");}QString {CLASSNAME}Plugin::includeFile() const{ return QLatin1String("");}
二、敲代码
mainwindow.h
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include <QFileSystemModel>#include <QTreeView>QT_BEGIN_NAMESPACEnamespace Ui { class MainWindow; }QT_END_NAMESPACEclass MainWindow : public QMainWindow{ Q_OBJECTpublic: MainWindow(QWidget *parent = nullptr); ~MainWindow(); bool checkForms(); void toString(); bool CopyDirectoryFiles(const QString &fromDir,const QString &toDir); bool changeFiles(const QString &dir); void changeFile(const QString &filePath); QString replace(const QString sourceStr); void renderTreeView(QFileSystemModel *fileSystemModel,QTreeView *view,const QString &dir);private slots: void on_pushButton_clicked(); void on_pushButton_2_clicked();private: Ui::MainWindow *ui; QString m_sourceDir; QString m_targetDir; QString m_fileName; QString m_className; QString m_macro; QString m_caseName; QString m_parentClassName; QString m_group; QString m_showName; QFileSystemModel *sourceFileModel; QFileSystemModel *targetFileModel;};#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"#include "ui_mainwindow.h"#include <QDebug>#include <QMessageBox>#include <QFileDialog>#include <QSettings>#include <QDir>MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow){ ui->setupUi(this); this->setWindowTitle (tr("初始化组件主动生成")); QDir dir(QCoreApplication::applicationDirPath ()); dir.cdUp (); this->m_sourceDir = dir.absolutePath ()+ "/" + "demo"; sourceFileModel = new QFileSystemModel(this); targetFileModel = new QFileSystemModel(this); //初始化数据 QSettings settings("setting.ini",QSettings::IniFormat); ui->classNameQLE->setText (settings.value ("classNameQLE").toString ()); ui->parentClassNameQLE->setText (settings.value ("parentClassNameQLE").toString ()); ui->groupQLE->setText (settings.value ("groupQLE").toString ()); ui->showNameQLE->setText (settings.value ("showNameQLE").toString ()); ui->targetDirQLE->setText (settings.value ("targetDirQLE").toString ());}MainWindow::~MainWindow(){ //退出保留配置 QSettings settings("setting.ini",QSettings::IniFormat); settings.setValue ("classNameQLE",ui->classNameQLE->text ()); settings.setValue ("parentClassNameQLE",ui->parentClassNameQLE->text ()); settings.setValue ("groupQLE",ui->groupQLE->text ()); settings.setValue ("showNameQLE",ui->showNameQLE->text ()); settings.setValue ("targetDirQLE",ui->targetDirQLE->text ()); delete ui;}bool MainWindow::checkForms(){ if(ui->classNameQLE->text ()== ""){ QMessageBox::critical (this,tr("谬误"),tr("请输出类名")); return false; } if(ui->parentClassNameQLE->text ()== ""){ QMessageBox::critical (this,tr("谬误"),tr("请输出父类名")); return false; } if(ui->groupQLE->text ()== ""){ QMessageBox::critical (this,tr("谬误"),tr("请输出组信息")); return false; } if(ui->showNameQLE->text ()== ""){ QMessageBox::critical (this,tr("谬误"),tr("请输出显示名称")); return false; } if(ui->targetDirQLE->text ()== ""){ QMessageBox::critical (this,tr("谬误"),tr("请抉择寄存目录")); return false; } return true;}void MainWindow::toString(){ qDebug()<<"文件名:" << m_fileName; qDebug()<<"类名:" << m_className; qDebug()<<"宏名:" << m_macro; qDebug()<<"实例名:" << m_caseName; qDebug()<<"父类名:" << m_parentClassName; qDebug()<<"组信息:" << m_group; qDebug()<<"显示名称:" << m_showName; qDebug()<<"源门路信息:" << m_sourceDir; qDebug()<<"指标门路信息:" << m_targetDir;}bool MainWindow::CopyDirectoryFiles(const QString &fromDir, const QString &toDir){ QDir sourceDir(fromDir); QDir targetDir(toDir); if(!targetDir.exists()) { if(!targetDir.mkdir(targetDir.absolutePath())) { return false; } } QFileInfoList list = sourceDir.entryInfoList(); for(int i = 0; i < list.size(); i++) { QFileInfo fileInfo = list.at(i); if(fileInfo.fileName()=="." || fileInfo.fileName()=="..") { continue; } if(fileInfo.isDir()) { if(!CopyDirectoryFiles(fileInfo.filePath(),targetDir.filePath(fileInfo.fileName()))) { return false; } } else { if(targetDir.exists(fileInfo.fileName())) { targetDir.remove(fileInfo.fileName()); //有雷同的,间接删除 } if(!QFile::copy(fileInfo.filePath(),targetDir.filePath(fileInfo.fileName()))) { return false; } } } return true;}bool MainWindow::changeFiles(const QString &dir){ QDir sourceDir(dir); if(!sourceDir.exists()) { return false; } QFileInfoList list = sourceDir.entryInfoList(); for(int i = 0; i < list.size(); i++) { QFileInfo fileInfo = list.at(i); QString filePath = fileInfo.filePath (); QDir dir(filePath); if(fileInfo.fileName()=="." || fileInfo.fileName()=="..") { continue; } changeFile(filePath); //重命名 dir.cdUp (); QString newName = fileInfo.fileName ().replace("demo",m_fileName); QFile::rename (dir.absolutePath ()+"/"+fileInfo.fileName (),dir.absolutePath ()+"/"+newName); } return true;}void MainWindow::changeFile(const QString &filePath){ QFile file(filePath); //以文件形式读出 QString str; //读取内容 if (file.open(QIODevice::ReadOnly)) { QTextStream s(&file); //用文本流读取文件 str = s.readAll (); } file.close(); //清空内容 file.open(QIODevice::ReadWrite | QIODevice::Truncate); file.close (); //替换内容 str = replace(str); //写入新内容 if (file.open(QIODevice::WriteOnly)) { QTextStream s(&file); s << str; } file.close();}QString MainWindow::replace(const QString sourceStr){ QString targetStr = sourceStr; //能够在这里减少其它变量替换 targetStr = targetStr.replace ("{FILENAME}",m_fileName); targetStr = targetStr.replace ("{CLASSNAME}",m_className); targetStr = targetStr.replace ("{PARENTCLASSNAME}",m_parentClassName); targetStr = targetStr.replace ("{MACRO}",m_macro); targetStr = targetStr.replace ("{SHOWNAME}",m_showName); targetStr = targetStr.replace ("{GROUP}",m_group); targetStr = targetStr.replace ("{CASENAME}",m_caseName); return targetStr;}void MainWindow::renderTreeView(QFileSystemModel *fileSystemModel,QTreeView *view, const QString &dir){ fileSystemModel->setRootPath(dir); view->setModel (fileSystemModel); view->setRootIndex(fileSystemModel->index(dir));}void MainWindow::on_pushButton_clicked(){ //校验数据 if(!checkForms ()){ return; } //赋值 QString classNameQLEText = ui->classNameQLE->text (); QString parentClassNameQLEText = ui->parentClassNameQLE->text (); QString groupQLEText = ui->groupQLE->text (); QString showNameQLEText = ui->showNameQLE->text (); QString targetDirQLEText = ui->targetDirQLE->text (); m_fileName = classNameQLEText.toLower (); m_className = classNameQLEText; m_macro = classNameQLEText.toUpper (); m_caseName = classNameQLEText.sliced (0,1).toLower() + classNameQLEText.sliced (1); m_parentClassName = parentClassNameQLEText; m_group = groupQLEText; m_showName = showNameQLEText; m_targetDir = targetDirQLEText + "/" + m_fileName; //拷贝目录 if(!CopyDirectoryFiles(m_sourceDir,m_targetDir)){ QMessageBox::critical (this,tr("谬误"),tr("拷贝目录失败!")); return; } //读取文件并替换 if(!changeFiles(m_targetDir)){ QMessageBox::critical (this,tr("谬误"),tr("文件批改失败!")); return; } //渲染view renderTreeView(sourceFileModel,ui->sourceTreeView,m_sourceDir); renderTreeView(targetFileModel,ui->targetTreeView,m_targetDir); QMessageBox::information (this,tr("胜利"),tr("组件生成胜利!"));}void MainWindow::on_pushButton_2_clicked(){ QString dir = QFileDialog::getExistingDirectory (this,"Select Directory","/",QFileDialog::ShowDirsOnly); ui->targetDirQLE->setText (dir);}
最初的成型: