Contents
前言模块化项目中的模块各个模块之间的依赖关系总结实战模块依赖链项目树项目代码
前言
又有二十多天没写推送了,还是在忙着找工作的事。另外疫情原因感觉学校又肯定要提前放假了,实验还没做,课题也还没有啥头序,有点慌
。工作定了后得抓紧学习了
。
今天这篇推送主要是前段时间项目开发中总结出来的部分经验,个人感觉还好,就花了一下午写了写来记录一下。
内容主要是用Qt开发桌面应用程序的UI代码框架。
模块化
项目中的模块
就以我的这个项目为例来说吧。
下图是我这个项目的所有模块,我只说说UI模块。
其中AST模块是一个单独的选项卡的窗口,用来设置一些东西:
libToolBar模块放的是构成整个界面程序的:标题栏、菜单栏、工具栏、状态栏:
Splash 模块,是一个启动界面,主要是用于完成软件的初始化操作:
MainWindow 模块,就是我们的主界面,所有的UI部分都在这个模块中拼接起来,构成用户界面。在我的项目中,这个模块下面还包含了一个子模块(StackedWidget)它是用作UI界面的中央窗口。
各个模块之间的依赖关系
各个模块之间是有依赖的,你必须要把他们链接起来,CMake可以很容易地解决这个问题,直接用下面这个命令就能解决
target_link_libraries(tgt PUBLIC library1 library2 ...)
下图是我这个项目中的各个模块之间的依赖关系:
后面我会新做一个模块化的小项目,然后大家再看看我之前写的那个CMake的文章应该可以实现模块化了:CMake总结----(1)
总结
上述的AST、libToolBar模块都仅仅用于完成信号的转发的操作,不要在这些模块中实现 触发该信号时要执行的功能,仅仅只是把这个信号转发出去而已。
所有的功能都在主界面模块中完成,或者你单独整一个模块也行。我这项目中就是把所有的功能放在主界面模块中的一个allSlots.cpp文件中实现的。或者在主界面模块中,你把每个UI模块对应的功能单独放到一个cpp文件中实现也可以。
这样做的好处就是后期维护起来非常方便。比如你想给菜单栏中新添加一个菜单按钮,你就可以直接进入菜单栏模块,然后在代码里new一个menu,然后在这个模块中创建一个信号,当触发该menu时转发该信号就行。然后在主界面模块中连接转发过来的信号和相应的槽函数。
过程十分清爽,如果你想修改功能的话,也只需要进入主界面模块找到相应的槽函数。而不用管这个信号从哪发过来的,直接改槽函数就行。
这样说用文字说可能不太好理解,下面我自己写一个简单的例子演示一下,简单起见就不做用户界面了。
实战
模块依赖链
下面是我写的一个模块化的例子,它有6个模块,每个模块之间的依赖关系如下图所示
这个图可以看出:
libModule2 依赖 libModule1
libModule3 依赖 libModule1
libModule4 依赖 libModule1 和 libModule5
libMainModule 依赖 libModule2 和 libModule3 和 libModule4
最后生成的可执行程序依赖 libMainModule
由于是写例子,所以每个模块我并没有设计实际的功能,仅仅是打印一下调用信息。
项目树
【Linux的tree命令真好用】
项目代码
项目代码不放在这了,我传到我的码云上去
,有兴趣的可以去clone一下。
https://gitee.com/mitchhong/modularization.git
这里放一下我的 主
CMakeList.txt
cmake_minimum_required(VERSION 3.15)
project(Modularization)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib)
add_subdirectory(MainModule) ## 主模块
add_subdirectory(Module1) ## 模块1
add_subdirectory(Module2) ## 模块2
add_subdirectory(Module3) ## 模块3
add_subdirectory(Module4) ## 模块4
add_subdirectory(Module5) ## 模块5
################ 处理各个模块之间的依赖 ################
## 模块2 依赖 模块1;设置为私有,依赖链下游不可访问
target_link_libraries(
libModule2
PRIVATE
libModule1
)
## 模块3 依赖 模块1;设置为私有,依赖链下游不可访问
target_link_libraries(
libModule3
PRIVATE
libModule1
)
## 模块4 依赖 模块1;设置为私有,依赖链下游不可访问
target_link_libraries(
libModule3
PRIVATE
libModule1
)
## 模块4 依赖 模块1和模块5;设置为私有,依赖链下游不可访问
target_link_libraries(
libModule4
PRIVATE
libModule1
libModule5
)
## 主模块 依赖 模块2、模块3、模块4;设置为私有,依赖链下游不可访问
target_link_libraries(
libMainModule
PRIVATE
libModule2
libModule3
libModule4
)
################ 生成主程序 ################
add_executable(Modularization main.cpp)
## 主程序依赖 主模块
target_link_libraries(
Modularization
PUBLIC
libMainModule
)
照着这个套一下就能实现模块化。如果你要引入外部库,无非就是像下面这样差不多:
###################################### Qt 相关 ######################################
set(Qt5_DIR "C:\\Qt\\Qt5_12_MSVC\\lib\\cmake\\Qt5") # Windows中
find_package(Qt5 COMPONENTS Core Gui Widgets Charts Sql REQUIRED)
set(CMAKE_AUTOMOC ON)
###################################### OpenSSL 库 ######################################
# 把 OpenSSL 的头文件的目录包括进来(固定的)
include_directories("C:/OpenSSL/OpenSSL_prefix/include")
# 把 OpenSSL 目录路径 链接进来
link_directories("C:/OpenSSL/OpenSSL_prefix/lib")
# 链接 OpenSSL
link_libraries(
"C:/OpenSSL/OpenSSL_prefix/lib/libcrypto.lib"
"C:/OpenSSL/OpenSSL_prefix/lib/libssl.lib"
)