在 Windows 平台下,使用 Visual Studio 搭建基于 CMake 的 QT 开发环境可以使开发者更加灵活地控制和管理 QT 项目的构建和配置。此过程需要在 Visual Studio 中安装并使用 CMake 工具,然后在 CMakeLists.txt 文件中添加适当的 QT 配置信息,以便编译、链接和生成 QT 项目。

        创建 CMake 项目可以让 QT 开发者更加轻松地管理项目依赖和库文件,并且可以在多个平台和不同的编译器中运行,从而大大提高了代码的可移植性和可维护性。在 Visual Studio 中为 QT 项目创建 CMake 项目,首先需要安装 CMake 工具以及适当的 QT 版本,然后在 Visual Studio 中创建一个 CMake 项目并配置 CMakeLists.txt 文件。

        利用 CMakeLists.txt 文件可以添加 QT 组件库、自定义编译选项、定义编译器路径等,从而更好地控制和管理 QT 项目的构建过程。使用 Visual Studio 搭建 CMake 项目可以让 QT 开发者更加专注于本质的应用程序开发,以便更加高效地构建、测试和发布 QT 应用程序。

 

  • 初次使用VS创建CMake项目时会出现一个out文件夹目录下存在CMakeLists.txt,CMakePresets.json,CMakeProject.cpp,CMakeProject.h这四个子目录 为了更好地学习与理解使用VS配置CMake进行QT开发,我在这里直接删除CMakeProject.cpp,CMakeProject.h文件,重新创建一个main.cpp文件,然后将CMakeLists.txt内的代码全部清空重新手写一遍,来加深理解,从而提升学习效率。
  • 重写后的解决资源管理器out文件夹目录下只存在三个子目录CMakeLists.txt,CMakePresets.json,main.cpp,其中CMakePresets.json暂时不动,通过手写CMakeLists.txt和main.cpp内的代码来加深理解与学习。
  •  下面是我对手写CMakeLists.txt和main.cpp的细节描述:

 

  • CMakeLists.txt文件内代码细节

         CMake是一个跨平台的自动化构建系统,它使用名为CMakeLists.txt的文本文件来描述项目的构建过程。这个文件可以通过编写简单的指令来创建编译过程,并且可以在不同的平台上使用相同的CMakeLists.txt文件来构建项目。

cmake_minimum_required (VERSION 3.8)

project (QtPro)

#指定C++标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if(MSVC)
	add_compile_options(/Zc:__cplusplus)
endif()

#指定头文件包含目录
include_directories("D:/Progm/QT/software/install/6.2.4/msvc2019_64/include")
#设置模块的cMake路径
set(CAMKE_PREFIX_PATH "D:/Progm/QT/software/install/6.2.4/msvc2019_64/lib/cmake")
#查找指定模块
find_package(Qt6 COMPONENTS Widgets REQUIRED)
#指定目标位置
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/bin)

# 将源代码添加到此项目的可执行文件。
add_executable (QtPro "main.cpp")

#将目标链接库文件
target_link_libraries(QtPro Qt6::Widgets)
message("My debug message:")

一个典型的CMakeLists.txt文件通常包含以下内容:

  1. 项目的名称和版本号

    cmake_minimum_required(VERSION 3.8)
    project(MyProject VERSION 1.0)
    
  2. 设置项目编译选项

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED True)
    #其中True可以用ON表示
    #set(CMAKE_CXX_STANDARD_REQUIRED ON)
    
  3. 设置编译器警告等级、开启特定的编译选项、设置编译器优化等级等

    if(MSVC)
    	add_compile_options(/Zc:__cplusplus)
    endif()
    
    #当编译器报错“/Zc:__cplusplus”时可以用这个方法来防止报错
  4. 添加包含目录和链接库目录

    include_directories(include)
    link_directories(lib)
    
  5. 设置和查找指定模块

    #设置模块的cMake路径    PS:注意!目录的“\”符号在项目中应换成“/”否则会报错
    set(CAMKE_PREFIX_PATH "D:/Progm/QT/software/install/6.2.4/msvc2019_64/lib/cmake")
    #查找指定模块
    find_package(Qt6 COMPONENTS Widgets REQUIRED)
    #
  6. 指定目标位置,指定编译生成的可执行文件的输出目录

    #指定目标位置 
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/bin)
  7. 添加库或可执行文件

    add_library(MyLibrary SHARED ${SOURCES})
    add_executable(MyExecutable ${SOURCES})
    
  8. 链接库和可执行文件

    target_link_libraries(MyLibrary MyOtherLibrary)
    target_link_libraries(MyExecutable MyLibrary)
    

PS:注意操作顺序!!!include_directories(include)的操作应该放在添加可执行程序add_executable(MyExecutable ${SOURCES})操作之前,链接库target_link_libraries(MyLibrary MyOtherLibrary)的操作应该放在添加可执行程序add_executable(MyExecutable ${SOURCES})操作之后!

  • 1. 规定CMake最低版本要求:cmake_minimum_required (VERSION 3.8)

  cmake_minimum_required (VERSION 3.8) 是一个CMake脚本的指令,它用于规定了构建该工程所需要的最低版本的CMake的版本号。意思是,只有高于或等于3.8版本的CMake才可以用来构建这个工程。

        这里的VERSION 3.8中的3.8是指CMake的主版本号和次版本号,它表示工程所需要的最低版本的CMake应该是3.8或更高的版本。

        在CMake脚本中使用cmake_minimum_required指令是一个基本的规范,它确保了整个项目所需要的最低版本的CMake已经安装,并且可以避免由于CMake版本不兼容而导致的构建失败。此外,这个指令同样也会用于告诉用户,这个工程需要使用哪个版本的CMake来进行构建。


PS:注意CMake版本号特点,3.16比3.8版本号要高!

        CMake版本号命名规则通常采用“主版本.次版本.修订版本”的格式,例如CMake 3.10.2表示主版本号为3,次版本号为10,修订版本号为2。

CMake的版本号命名特点如下:

  1. 主版本号:

    第一位数字表示主版本号。当CMake的主要功能、架构或其它改动较大时,主版本号会增加。

  2. 次版本号:

    第二位数字表示次版本号。当CMake添加新功能或允许某些功能的参数改变时,次版本号会增加。

  3. 修订版本号:

    第三位数字表示修订版本号。修订版本号表示缺陷修复、文档更新或测试用例等的变化。修复bug、增加测试用例等小调整都会使修订版本号增加。

        CMake还有一个预发布版本号(也称为“预览版”或“rc版”),标识为“rcX”或“betaX”,X为数字。例如CMake 3.14.0-rc1表示预发布版1,这个版本是未正式发布的测试版本。预发布版本号主要用于公开测试和反馈,便于开发者收集反馈和改进程序。

总之,CMake版本号命名方式符合主流的数字版本命名规范,清晰明了。在使用CMake时,需要注意CMake版本号的兼容性问题。

  • 2. project()命令,用于定义C++项目的名称、版本号等信息。
  • qmake中的project()命令

        在使用QT开发程序时,通常会使用QT提供的qmake工具来生成Makefile和可执行程序。而qmake则会使用project()命令来定义项目。

project()命令用于定义C++项目的名称、版本号等信息。其基本语法如下:

project(project_name [VERSION major[.minor[.patch[.tweak]]]]
        [DESCRIPTION "description"]
        [LANGUAGES language_name ...])

其中:

  • project_name:项目名称
  • VERSION:可选,项目版本号,格式为major.minor.patch.tweak
    • major:主版本号
    • minor:次版本号
    • patch:修订版本号
    • tweak:错误修正版本号
  • DESCRIPTION:可选,项目描述
  • LANGUAGES:可选,项目所用的语言

例如:

project(MyProject VERSION 1.0.0 DESCRIPTION "A sample project" LANGUAGES CXX)

        这行代码定义了一个名为"MyProject"的项目,版本号为1.0.0,描述为"A sample project",使用的编程语言为C++。

在使用QT开发程序时,除了定义项目信息,还通常会在project()命令中指定QT使用的模块,例如:

project(MyProject VERSION 1.0.0 DESCRIPTION "A sample project" LANGUAGES CXX)

find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
find_package(Qt5Widgets REQUIRED)

target_link_libraries(MyProject Qt5::Core Qt5::Gui Qt5::Widgets)

        这里使用了find_package()命令来查找QT的Core、Gui和Widgets模块,并将它们链接到可执行文件中。

总之,在使用QT开发程序时,project()命令是定义项目的关键步骤,它可以帮助我们清晰地组织代码,并指定QT应该使用的模块和版本信息。

  • cmake中的project()命令

        在使用CMake构建QT项目时,同样可以使用project()命令来定义项目信息。不同的是,project()命令需要结合QT库的查找和链接使用。

基本的project()指令语法如下:

project(project_name
    VERSION version
    DESCRIPTION description
    LANGUAGES CXX
)

        其中,project_name是项目名称,version是项目版本号,description是项目描述。注意,在使用QT开发程序时,要在CMakeLists.txt中添加以下代码来定位QT和自动moc文件:

set(CMAKE_AUTOMOC ON)
find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)

        在project()命令中可以使用如下方式设置QT版本:

set(QT_VERSION_MAJOR 5)
set(QT_VERSION_MINOR 15)
set(QT_VERSION_PATCH 0)
set(QT_VERSION "${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}")

project(MyProject VERSION ${QT_VERSION} LANGUAGES CXX)

        这段代码定义了一个名为MyProject的C++项目,依赖于QT 5.15.0版本,并使用了C++编程语言。项目版本号与QT版本号保持一致。

在使用target_link_libraries()命令指定链接库时,需使用QT提供的链接库,例如:

target_link_libraries(MyProject Qt5::Core Qt5::Gui Qt5::Widgets)

        这里使用了QT的Core、Gui和Widgets链接库。

综上所述,当使用CMake构建QT项目时,需要在project()命令中指定项目信息、QT的版本号和使用的编程语言,并使用find_package()命令查找QT库和使用target_link_libraries()命令链接QT库。

  •  3. 设置项目编译选项,指定C++标准

        在CMake中,set()命令用来设置变量,CMAKE_CXX_STANDARDCMAKE_CXX_STANDARD_REQUIRED是用来设置C++编译标准和是否强制使用该标准的变量。

具体来说,CMAKE_CXX_STANDARD可以设置编译器使用的C++标准版本号(如C++11、C++14、C++17等)。例如:

set(CMAKE_CXX_STANDARD 17)

        这段代码将C++编译器的标准版本设置为C++17。

CMAKE_CXX_STANDARD_REQUIRED设置成True表示必须使用指定的C++标准版本进行编译,否则将会出现编译错误(其中True也可以用ON代替)。例如:

set(CMAKE_CXX_STANDARD_REQUIRED True)
#set(CMAKE_CXX_STANDARD_REQUIRED ON)

        这段代码表示要求编译器必须按照CMAKE_CXX_STANDARD所设定的标准进行编译。

总之,set(CMAKE_CXX_STANDARD 17)set(CMAKE_CXX_STANDARD_REQUIRED True)命令用于设置C++编译标准和是否强制使用该标准。在进行C++开发过程中,可以通过这两个命令指定C++标准版本,同时要求编译器必须按照指定标准进行编译,从而提高程序的可移植性和安全性。

  • 4. add_compile_options()命令,设置编译器警告等级、开启特定的编译选项、设置编译器优化等级等。

        在CMake中,add_compile_options()命令用来向文件级别编译器传递指定的编译选项。具体来说,它可以用来设置编译器警告等级、开启特定的编译选项、设置编译器优化等级等。该命令可以用于单个源文件或整个target。

例如,以下代码将编译选项-Werror添加到源文件的编译选项中,这样任何编译器警告都会被视为错误并导致编译失败:

add_executable(my_program my_program.cpp)
add_compile_options(-Werror)

        下面这个示例会向C++编译器添加-O3优化选项,对整个target进行编译器优化:

add_executable(my_program my_program.cpp)
add_compile_options(-O3)

        除了单个编译选项外,还可以使用以下方式添加多个选项:

set(SIMPLE_OPTS "-Wall" "-pedantic" "-Wextra")
add_compile_options("$<$<CONFIG:Debug>:${SIMPLE_OPTS}>" "$<$<CONFIG:Release>:${SIMPLE_OPTS} -O3>")

        这样既向源文件的调试版本(CONFIG:Debug)添加了-Wall-pedantic-Wextra编译选项,也向发布版本(CONFIG:Release)添加了这些选项和-O3优化选项。

总之,add_compile_options()命令可以用来向target、file,和其他地方添加编译器选项。通过使用该命令可以灵活地控制编译器选项,实现代码优化等目的。

  • 5. 添加库和链接库,include_directories()link_directories()都是用来设置编译器的搜索路径,分别用来设置头文件包含路径和库文件链接路径。

        在CMake中,include_directories()link_directories()都是用来设置编译器的搜索路径,分别用来设置头文件包含路径和库文件链接路径。

  • include_directories():该命令用于向编译器中添加头文件的搜索路径,使编译器能够正确地找到要包含的头文件。include_directories()中指定的路径将直接添加到整个CMake项目的所有编译器选项中。语法如下:
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])

        其中:

- `AFTER`和`BEFORE`表示添加目录的位置,`AFTER`表示将目录放在原目录后面,`BEFORE`表示将目录放在原目录前面;
- `SYSTEM`表示添加系统目录,可以避免一些警告信息;
- `dir`表示你要添加的目录。

        例如:

include_directories(include)

        这样就将include目录添加到了CMake项目的头文件搜索路径中。

  • link_directories():该命令用于向链接器中添加库文件的搜索路径,类似于include_directories()link_directories()中指定的路径将直接添加到整个CMake项目的所有链接器选项中。语法如下:
link_directories(directory1 [directory2 ...])

        其中:

- `directory`表示要添加的库文件搜索路径。

        例如:

link_directories(lib)

        这样就将lib目录添加到CMake项目的链接器选项中,链接器可以在该目录中搜索程序需要的库文件。

总之,include_directories()link_directories()这两个命令都是用于设置编译器的搜索路径,分别用于设置头文件包含路径和库文件链接路径。通过使用这两个命令,可以使编译器和链接器能够正确地找到所需要的文件,保证程序的正确编译和链接。

  • 6. 设置和查找指定模块,set()find_package()命令通常是一起使用的,用于设置和查找指定模块。

        在CMake中,set()find_package()命令通常是一起使用的,用于设置和查找指定模块。

  • set(CMAKE_PREFIX_PATH "path1" "path2" ...): 该命令用于设置CMake查找CMake模块的根目录,可以指定多个路径。在这些目录下,CMake会按照一定的方式查找CMake模块。语法如下:
set(CMAKE_PREFIX_PATH "path1" "path2" ...)
  • find_package(packageName [version] [EXACT] [QUIET] [REQUIRED] [COMPONENTS <component1> <component2> ...]):该命令用于查找指定的模块并加载对应的配置。通常被用于查找和加载第三方库的CMake模块。语法如下:
find_package(packageName [version] [EXACT] [QUIET] [REQUIRED] [COMPONENTS <component1> <component2> ...])

        其中,

  • packageName:要查找的模块名称;
  • version:模块的版本号;
  • EXACT:是否要求包的版本必须精确匹配;
  • QUIET:是否关闭错误和警告信息;
  • REQUIRED:是否要求模块必须找到;
  • COMPONENTS:用于指定要查找的组件。

        例如:

set(CMAKE_PREFIX_PATH "D:/Progm/QT/software/install/6.2.4/msvc2019_64/lib/cmake")
find_package(Qt6 COMPONENTS Widgets REQUIRED)

        这里指定了Qt6的CMake模块路径,并查找Qt6 Widgets组件。

总之,set(CMAKE_PREFIX_PATH)find_package()命令通常被一起使用,用于设置和查找指定模块,并加载对应的配置。通过这两个命令,可以方便地导入第三方库的CMake模块,并使用其中所包含的组件。

  • 7.  指定目标位置,使用set(CMAKE_RUNTIME_OUTPUT_DIRECTORY)命令可以指定编译生成的可执行文件的输出目录。 

        在CMake中,使用set(CMAKE_RUNTIME_OUTPUT_DIRECTORY)命令可以指定编译生成的可执行文件的输出目录。

该命令的基本语法如下:

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY directory)

        其中,directory是可执行文件的输出目录,可以是相对路径或绝对路径,如果指定的目录不存在,CMake将自动创建该目录。

例如,以下代码将生成的可执行文件输出到项目根目录的bin子目录中:

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/bin)

        这样,编译生成的可执行文件就会被输出到bin目录中,便于管理。

在默认情况下,如果没有通过set(CMAKE_RUNTIME_OUTPUT_DIRECTORY)命令指定生成的可执行文件的输出路径,则CMake会将其输出到构建目录中(build目录或Debug/Release子目录中)。通过使用该命令,可以方便地指定可执行文件的输出目录,便于自定义和管理。

总之,set(CMAKE_RUNTIME_OUTPUT_DIRECTORY)命令可以用于指定编译生成的可执行文件的输出目录,使得输出文件位置可控,更方便地管理和部署程序。

  • 8.  添加库或可执行文件,add_library(MyLibrary SHARED ${SOURCES})
    add_executable(MyExecutable ${SOURCES})

        在CMake中,使用add_library()命令可以添加一个库文件(静态库或动态库),使用add_executable()命令可以添加一个可执行文件。

  • add_library():该命令用于将源代码构建为一个库文件,并将其添加到CMake项目中。该命令可以创建静态库或动态库。语法如下:
add_library(libName [STATIC | SHARED | MODULE] source1 [source2 ...])

        其中,libName为目标库的名称,STATIC表示创建一个静态库,SHARED表示创建一个动态库,MODULE表示创建一个可加载模块。source1source2是库的源代码文件。

例如:

add_library(MyLibrary SHARED ${SOURCES})

        这样就创建了一个名为MyLibrary的动态库,并将${SOURCES}中的源代码文件编译为该库。

  • add_executable():该命令用于将源代码构建为一个可执行文件,并将其添加到CMake项目中。语法如下:
add_executable(execName source1 [source2 ...])

        其中,execName为目标可执行文件的名称,source1source2是可执行文件的源代码文件。

例如:

add_executable(MyExecutable ${SOURCES})

        这样就创建了一个名为MyExecutable的可执行文件,并将${SOURCES}中的源代码文件编译为该可执行文件。

总之,通过使用add_library()add_executable()命令,可以将源代码文件编译为库文件或可执行文件,并将其添加到CMake项目中进行管理和构建。这两个命令是CMake中非常重要的基础命令之一,涵盖了项目编译构建中最核心的部分。

  •  9. 链接库和可执行文件,target_link_libraries(MyLibrary MyOtherLibrary)
    target_link_libraries(MyExecutable MyLibrary)

        在CMake中,使用target_link_libraries()命令可以将目标文件与指定的库文件进行链接,将所需的库文件作为目标文件的依赖项。

  • target_link_libraries():该命令用于将指定的库文件链接到目标文件中,以满足目标文件的依赖关系。语法如下:
target_link_libraries(target library1 [library2 ...])

        其中,target为目标文件(可执行文件、静态库或动态库)名称,library1library2为指定的库文件名称。

例如,以下代码将MyLibrary链接到MyExecutable中:

target_link_libraries(MyExecutable MyLibrary)

        这样,构建MyExecutable时就会自动将MyLibrary库文件链接进去以满足依赖关系。

另外,target_link_libraries()还可以用于将一个目标文件链接到另一个目标文件中,将一个库文件链接到另一个库文件中,还可以链接系统库。

总之,通过使用target_link_libraries()命令,可以将目标文件与指定的库文件进行链接,使目标文件能够成功编译和执行。

  • 10. 使用message()命令输出自定义的调试信息或提示信息 。

在CMake中,可以使用message()命令输出自定义的调试信息或提示信息。这个命令在QT项目中同样适用。

  • message():该命令用于输出自定义的信息或提示信息。语法如下:
message("message content")

其中,message content为要输出的信息或提示信息内容。

例如,以下代码输出一个自定义的调试信息:

message("My debug message")

在QT项目中,也可以使用该命令输出提示信息或调试信息。使用message()命令可以方便地输出一些关键性的信息,如:环境变量、路径信息、编译选项等等,以方便调试和排查问题。

总之,message()命令是一个常用的调试工具,可以方便地输出自定义的调试信息或提示信息,用于代码的开发和调试。


  • 学习所用实例代码
    #CMakeLists.txt下的代码
    
    cmake_minimum_required (VERSION 3.8)
    
    project (QtPro)
    
    #指定C++标准
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    
    if(MSVC)
    	add_compile_options(/Zc:__cplusplus)
    endif()
    
    #指定头文件包含目录
    include_directories("D:/Progm/QT/software/install/6.2.4/msvc2019_64/include")
    #设置模块的cMake路径
    set(CAMKE_PREFIX_PATH "D:/Progm/QT/software/install/6.2.4/msvc2019_64/lib/cmake")
    #查找指定模块
    find_package(Qt6 COMPONENTS Widgets REQUIRED)
    #指定目标位置
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/bin)
    
    # 将源代码添加到此项目的可执行文件。
    add_executable (QtPro "main.cpp")
    
    #将目标链接库文件
    target_link_libraries(QtPro Qt6::Widgets)
    message("My debug message:")
  • main.cpp文件内代码细节
#include<QApplication>
#include<QWidget>
#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
int main(int argc, char* argv[]) {
	
	QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
	QApplication a(argc, argv);
	QWidget w;
	w.show();
	return a.exec();

}
  • 1. QApplication、QWidget头文件的引入需要在CMakeLists.txt中先设置qt6模块的cMake路径然后查找Widgets模块,然后在目标中链接库文件,具体对应CMakeLists.txt中的
    #设置模块的cMake路径
    set(CAMKE_PREFIX_PATH "D:/Progm/QT/software/install/6.2.4/msvc2019_64/lib/cmake")
    #查找指定模块
    find_package(Qt6 COMPONENTS Widgets REQUIRED)
    
    #将目标链接库文件
    target_link_libraries(QtPro Qt6::Widgets)

    PS:注意!如果环境变量没有添加msvc2019_64\bin和CMake_64\bin的话容易出现报错说找不到指定模块,笔者开始就因为没有添加导致一直报错。

  • 2. 入口函数与QApplication类的使用

           在QT中,int main(int argc, char* argv[])同样是程序的入口函数,其作用与C++中的入口函数相同。

    例如:

    #include <QApplication>
    
    int main(int argc, char* argv[]) {
        QApplication app(argc, argv);
        // 创建并显示主窗口等其他操作...
        return app.exec();
    }
    

           在QT中,建议使用QApplication类来管理应用程序的生命周期,以便能够更好地处理事件循环和退出应用程序等操作。在main函数中,可以使用QApplication类的构造函数来初始化应用程序,创建主窗口等其他部件,然后通过调用QApplication::exec()函数进入主循环,等待事件发生,使用QApplication类的exec()函数进入事件循环,让窗口等其他部件能够接收并处理事件。

  • 3. 消除黑窗口

           在 Windows 平台上,Qt 程序在编译运行时都会有一个黑色的控制台窗口出现。这个窗口会显示一些系统和运行时信息,但对于大多数图形化界面应用程序来说,这个窗口显然不是必要的,而且可能会影响用户体验。

    以下是几种消除黑窗口的方法:

    • ①CMake 配置选项
      • CMake 是一个跨平台的构建工具,可以在项目构建时通过设置配置选项来控制生成的程序是否出现命令行窗口。在 Windows 平台上,可以使用 CMAKE_WIN32_EXECUTABLE 选项来控制生成的可执行程序是否有命令行窗口。

        set(CMAKE_WIN32_EXECUTABLE [ON | OFF])
        

        启用 CMAKE_WIN32_EXECUTABLE 选项会将生成的可执行程序标记为 Windows 应用程序,从而避免程序启动时出现黑色控制台窗口。

    • ②#pragma 指令
      • #pragma 是预处理器指令的一种,在代码中可用于向编译器提供特殊的编译、链接或其他配置信息。在 Windows 平台上,可以使用 #pragma 指令来设置生成的可执行文件为 Windows 应用程序,从而消除黑色命令行窗口。
      • #ifdef WIN32
        #pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
        #endif
        

        这段代码会在程序入口函数前插入一段 #pragma 指令,用于设置生成的可执行文件的子系统为 Windows,并指定程序入口函数为 mainCRTStartup,从而消除黑色命令行窗口。

    • ③使用 WinMain()。
      • 在 Windows 平台上,可执行文件默认的入口点是 WinMain(),而不是标准的 main() 函数。这意味着如果我们使用标准的 main() 函数作为程序入口点,编译器会自动为程序生成一个控制台窗口。因此,如果想要消除黑窗口的出现,可以将程序入口点改为 WinMain()。但是这个方法需要一些特定的编码技巧,具体可以参考 Qt 中 WinMain 的实现

      • 需要注意的是,如果我们使用 #pragma 指令或将入口点改为 WinMain(),那么在程序运行时就不能再使用标准输出等命令行接口。如果需要将信息输出到标准输出,可以使用 Qt 提供的 qDebug() 函数或使用 Qt Creator 中的 Debug 视图来查看程序输出。

      • 综上所述,可以根据实际情况选择适合自己的方法来消除黑窗口。其中,使用 CMake 配置选项会更通用和便于管理,而 #pragma 和 WinMain() 方法则更适用于特定的情况和需求。

    • 4. 设置应用程序全局属性

      • QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling)是一个在QT中设置应用程序全局属性的语句。它的作用是启用高分辨率缩放支持,使得应用程序具有更好的在高分辨率屏幕上显示的能力。

      • 在QT中,不同的应用程序有不同的全局属性,可以通过QCoreApplication::setAttribute()函数来设置。其中,Qt::AA_EnableHighDpiScaling参数表示启用高分辨率缩放支持。

      • 在高分辨率屏幕上运行未开启高分辨率缩放支持的应用程序,可能导致字体、图像等出现模糊不清的情况。而启用了高分辨率缩放支持后,操作系统和QT框架会自动根据屏幕像素密度的不同,对应的调整界面元素的大小和分辨率,使其在高分辨率屏幕上显示更为清晰。在一些高分辨率的显示设备上,启用高分辨率缩放支持,能够显著提升应用程序的用户体验。    

      • 因此,QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling)语句是在QT中非常常见的,用于配置应用程序高分辨率缩放支持的全局属性。

    • 学习所用案例代码

      #include<QApplication>
      #include<QWidget>
      
      #pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
      
      int main(int argc, char* argv[]) {
      	
      	QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
      	QApplication a(argc, argv);
      	QWidget w;
      	w.show();
      	return a.exec();
      
      }













 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐