当前位置: 首页 > Linux

Qt插件编程实践

时间:2023-04-07 03:05:16 Linux

原因是最近在用Qt做项目,在网上找插件写的资料。没有完整代码,要下载的资源全部上传到需要学分的网站。于是把插件示例工程写的完整,在github上开了一个qtDemo工程,写了这篇文章。作为一个拖砖项目,希望大家在学习的同时不要忘记分享的精神。我会在这个项目中继续更新学习Qt的代码。如果你有伙伴,请向我提出请求。本项目收集Qt示例程序,谢谢!技术选择我的项目至少支持msvc10.0x86、g++4.8.5、Qt5.5.1,因为需要跨平台,项目管理使用cmake(最低支持3.10),现在支持windows和linux,IDE我用的是qcreator,windows下也可以选择visualstudio2019.cmake介绍cmake的使用主要是因为它是跨平台的,可以脱离操作系统和IDE的束缚,得到了广泛的支持。设置最小版本号cmake_minimum_required(VERSION3.10)项目和版本号,项目名称可以通过${PROJECT_NAME}project(plg1VERSION0.1.0)将当前目录添加到文件中包含搜索目录,如果没有设置,vs2019和qcreator的当前目录会不兼容。set(CMAKE_INCLUDE_CURRENT_DIRON)打开globalmoc和globaluicset(CMAKE_AUTOMOCON)set(CMAKE_AUTOUICON)找到系统中安装的Qt版本和需要的库。最好每个库都写好,Qt会根据依赖关系自动添加find_package(Qt5REQUIREDWidgets)find_package(Qt5Widgets)find_package(Qt5Core)find_package(Qt5Gui)。需要创建一个名为QTDIR的系统环境变量,并指定Qt的安装目录。收集我们的源文件的方式有很多种,您可以按照自己喜欢的方式学习和使用。FILE(GLOBSRC_FILES"*.cpp""*.h""*.ui")创建工程文件add_executable(${PROJECT_NAME}${SRC_FILES})#可执行文件创建方法add_library(${PROJECT_NAME}SHARED${SRC_FILES})#动态链接库创建方法添加子项目,即我们的插件add_subdirectory(sub1)add_subdirectory(sub2)添加Qt5依赖target_link_libraries(${PROJECT_NAME}Qt5::WidgetsQt5::CoreQt5::Gui)Qt5pluginProject结构本示例项目包括三个项目,一个主项目和两个插件项目。cmake项目是基于目录的,每个项目的目录下都会有一个cmakelists.txt项目文件。主工程中的插件基类Plugindemoplugin.h是所有插件的基类。我们的每一个插件都继承自这个类,它做出了插件的基本声明以及我们的插件可以做的行为。本例中,每个插件都会返回一个widget给主程序作为centerWidget展示,并提供名称和信息查询接口,为插件提供必要的信息。类QtPluginDemoInterface{public:virtual~QtPluginDemoInterface(){}virtualQStringname()=0;虚拟QString信息()=0;虚拟QWidget*centerWidget()=0;//返回一个Widget并设置到centerwidget中显示};//s声明接口#definePluginDemoInterface_iid"com.Interface.MainInterface"Q_DECLARE_INTERFACE(QtPluginDemoInterface,PluginDemoInterface_iid)插件定义我们只解释sub1,sub2类似,请自行阅读代码。子工程的工程文件(cmakelists.txt)与主工程的主要区别在于,一个是创建可执行文件,一个是创建动态链接库。头文件plugindemo.h:#include"../plugindemoplugin.h"classpluginDemo:publicQObject,QtPluginDemoInterface{Q_OBJECT//Qt类的标识宏,初学Qt的朋友要注意了,这一行是必须的fortheQtclassQ_INTERFACES(QtPluginDemoInterface)//这两行声明是插件需要的Q_PLUGIN_METADATA(IIDPluginDemoInterface_iid)public:pluginDemo(){};...//方法声明,省略};源文件plugindemo.cpp:QWidget*pluginDemo::centerWidget(){autobtn=newQPushButton("One");//我们返回一个按钮作为一个简单的widget例子returnbtn;}...//其他的省略,只返回固定的信息给主程序加载插件mainwindow.hDefinition:QT_BEGIN_NAMESPACEnamespaceUi{classMainWindow;}QT_END_NAMESPACEclassMainWindow:publicQMainWindow{Q_OBJECTpublic:MainWindow(QWidget*parent=nullptr);?主窗口();intMainWindow::loadPlugins();voidMainWindow::loadPlugins();*我);voidMainWindow::slt_WidgetActionTriggered();private:Ui::MainWindow*ui;};通过loadPlugins函数加载插件:intMainWindow::loadPlugins(){Q目录pluginsDir=QDir(QCoreApplication::applicationDirPath());//这里注意路径需要配置好,将子工程的输出目录配置到主工程中if(!pluginsDir.cd("plugins"))return-1;//下的plugins目录下foreach(QStringfileName,pluginsDir.entryList(QDir::Files)){QPluginLoaderpluginLoader(pluginsDir.absoluteFilePath(fileName));QObject*plugin=pluginLoader.instance();如果(插件){autocenterInterface=qobject_cast(插件);如果(centerInterface){populateMenus(插件,centerInterface);//使用插件作为菜单中的一个项目}}}returncount;}生成菜单函数:voidMainWindow::populateMenus(QObject*pluginInterface,QtPluginDemoInterface*i){staticautomenu=menuBar()->addMenu(“小工具”);//创建一个菜单项autoact=newQAction(i->name(),pluginInterface);//创建action,获取到的插件对象绑定到它上面connect(act,&QAction::triggered,this,&MainWindow::slt_WidgetActionTriggered);//事件链接menu->addAction(act);}菜单点击事件响应:voidMainWindow::slt_WidgetActionTriggered(){QtPluginDemoInterface*plg=qobject_cast(sender()->parent());//获取插件对象autocenterWidget=plg->centerWidget();//获取插件返回的widget//我们返回的widget其实是一个QPushButton,利用它的配置信息为其设置显示内容(qobject_cast(centerWidget))->setText(plg->信息());setCentralWidget(centerWidget);}项目地址https://github.com/zhoutk/qtDemo命令行编译gitclonehttps://github.com/zhoutk/qtDemocdqtDemo/plugin&mkdirbuild&cdbuildcmake..cmake--build.编译时注意:cmake默认是x86架构,需要对应你安装的Qt版本;编译后运行前注意目录结构是否正确抛砖引玉,不吝赐教,感谢阅读!