文章目录
概述
考虑到A项目后期要将相关功能库用C#做外壳封装,也因为使用VS相比QtCreator有更强大的调试能力,决定使用VS2015+Qt5.12作为近期项目的集成开发环境。总结了最近3个月内遇到的一些IDE联合使用的问题。关于VS项目属性页中与Qt无直接关联的配置项,此文基本不涉及。
安装VS2015
略,请参照其他相关文档。
安装Qt VS Tools 插件
有两种方案。
方案1是从Qt官网下载 相关的插件,如qt-vs-addin-msvc2015-2.0.0-beta. vsix ,然后直接双击安装即可(在VS工具-扩展和更新中,并未找到安装离线插件的选项)。
方案2是直接在VS中进行插件扩展(菜单 - 工具 - 扩展和更新 - 搜索Qt),搜索到插件后在线安装。
相比较之下,方案2是以VS为主线的,它自动提供的插件版本,应该是与Qt对应版本提供的插件版本存在区别的。如果安装环境可以直接联网,建议方案2。
Qt相关配置应用到所有项目
通常的,在项目 - 属性中进行的配置只能对当前项目生效,按照如下方案可对所有项目生效(同样,在取消时,可按照单个项目进行取消,或对所有项目进行取消)。需要首先打开VS属性管理器(视图-其他窗口-属性管理器),后续步骤参照下文。
配置增加
在左侧切换到属性管理器中,如下图选择 Microsoft.Cpp.x64.user 然后右键 --> 选择属性 --> 配置方式与对单独项目进行配置是一样的。
注意:上图中蓝色选中处的配置,是错误的,不可借鉴。
配置删除
务必注意,通过Microsoft.Cpp.x64.user进行的所有项目参数配置,在单独项目配置时,是只读的,并不能进行修改。比如,上图中,我在探索阶段,错误的配置增加了 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib 目录,当进行具体的项目设置时,想在同样的位置将它删除,是办不到的。
Qt工程配置(Qt Project Settings)
Qt Versions
… 参见 Qt installation 错误 小节…
Qt Modules
参见,下文常见编译错误。所有用到的Qt模块都要包含进去,否则,相关模块的类接口将在编译时,报错找不到。在高版本的插件中是可以通过勾选操作实现此条目的编辑的。Qt的模块名字去除Qt字符并小写化,便是此处应该添加的字符串。包括:core;gui;widgets;xml;serialport;network…
有时候,即使你正确添加了模块名称,VS编辑器依然在相关类上提示红色波浪线,此时你可以重新扫描解决方案,必要时重启VS软件。另外,注意Debug和Release都要配置哦。
后来发现,在Qt项目的创建向导中,可以UI操作形式进行Qt Modules的具体配置,如下:
编辑器找不到Qt的类
问题现象大约是这样的,搞个简单的Demo可以编译成功,但是编辑器中显示Qt的全部类都是不识别的符号,注意这里是编辑器不是编译器。
一般情况下,遇到此类问题,只需要在VS资源管理树的项目名称上,右键,然后执行 “重新扫描解决方案” 即可。若不行,可以尝试重新启动VS软件,再次重新扫描解决方案,如果还是不行,可以看看后边的这些记录。
可以还有两种方案可以解决此问题:
方案1:
在项目属性 -> VC++目录 -> 包含目录中,添加D:\Qt\Qt5.12.8\5.12.8\msvc2015_64\include路径
方案2
在项目属性 -> Qt Project Setting -> Paths -> 头文件搜索路径 选项下,编辑-并插入 Qt_INCLUDEPAT宏,效果如下图。
后来,偶然发现:
在项目属性-> C/C++ -> [附加包含目录] 选项中,已经包含了$(Qt_INCLUDEPATH_); 通过查看同事的开发环境,这个配置应该是在进行Qt Project Setttings 附加目录,就已经默认自己存在了,只是,只是,没有编辑器起作用,但是我猜测,之所以编辑器告警,编译器不告警,其根本原因就是这个C/C++ -> [附加包含目录] 中的 $(Qt_INCLUDEPATH_); 对编译器起作用,对编辑器不起作用,我也是醉了!!
还有更加奇怪的(没有再详细测试)
当同事想在 项目属性 Qt Project Setttings -> Additional Qt Header search paths 中增加 $(Qt_INCLUDEPATH_) ;时,却发现他的宏列表中根本就没有这个选项。诡异的是,我的宏列表里也找不到它了,我昨天刚刚从宏列表里将它添加进去的啊! 我在编辑界面,将左侧的 $(Qt_INCLUDEPATH_) 删除保存,然后重新打开,还是找不到啦…
好在经过同事验证,在Additional Qt Header search paths中,手动的将 $(Qt_INCLUDEPATH_) 写入,对编译器也是生效的…
再次遇见奇怪的事情(20221012)
今天首次编译Release版本,准备发布出来测试用。在编译release版本时,先是遇到了Qt Project Setttings -> Qt Modules 配置中缺失 gui;widgets 模块导致的编译错误,轻松解决;之后又发现了编辑器红色波浪线提示,找不到任何的Qt类类型,可是,可是,Additional Qt Header search paths 已经正确配置了啊…
我删除了Qt相关的编译中间文件,重新编译,重新打开代码文件,这个问题就消失了,再不行,亲可尝试重新打开VS试试,或者试试资源树上的重新扫描解决方案…
20230203 工作过程需要,将代码重新从git上clone份,打开新目录下的工程A和B进行编译:再次遇到了编辑器告警Qt类不识别(红色下划线标记)的问题,编译结果无误,Qt Project Setttings配置正确。起初尝试重新编译无效,关闭工程重新打开无效。后来,对工程A进行了一次 “重新扫描解决方案”,暂无效,在此基础上再次关闭VS后重新打开工程A,不识别的问题便不存在啦。打开B工程(未执行重新扫描解决方案),发现其也不再有Qt类不识别的编辑器告警。
QtDesigner在VS下使用
首先,QtDesigner在VS下的使用,相比其在QtCreator下的使用,在功能上是有所阉割的,不要指望像在原生态下的那种好用。
无法打开UI/打开失败
ui文件无法打开,或者打开后闪退,或者是打开后报错(如:未完成的操作、未指定的错误;未将对象应用设置到对象的实例…)。
常用解决方案:
选中一个UI文件,右键 - 打开方式 - 添加 - 选中Qt安装目录下(D:\Qt\Qt5.12.8\5.12.8msvc2015_64\bin\)designer.exe 文件,并重新命名,且设置为默认值。
找不到UI编译中间文件
无论如何,首先要先进行一次编译,以使得绘制的UI文件,经过moc编译,生成ui_xxx.h中间文件。默认的存储路径为 …\x64\Debug\uic
这个中间文件的目标路径,应该是可以修改的,且此文件夹路径,应该是要配置到include路径下的。
UI添加的新控件在VS中不识别
如果安装了小番茄,在其设置 Enhanced Listboxes -> Source of C/C++ content: 选择 Default Intellisense,若选择visual assist是识别不到的,详细原因未知。
使用QtDesigner设计师编辑完了UI文件,并确定执行了保存操作,执行了编译过程,查看对应的ui_xxx.h文件,也没有问题,但是在引用ui_xxx.h头文件的VS代码文件中,愣是说找不到新加入的控件!解决方案如下:
- 先在ui编辑页面保存新的ui界面 。
- 在资源管理树,右键点击ui文件,然后选择编译
- 在资源管理树,选中项目,右键,然后选择重新扫描解决方案。
Qt 动态库的部署设置
在一个安装和定义良好的VS+Qt集成开发环境下,VS项目对Qt动态库的部署(包括.h头文件、.lib导入文件)是不需要额外配置的,当你在VS下新建Qt类型项目时,在Qt VS Tools的加持下,IDE会为你自动添加Qt动态库相关默认路径。以新建Qt Widgets项目为例,默认配置界面如下,
上述配置表格项的操作说明,
表格第一列Configuration是可以编辑的,允许输入任意名称;表格第五列Debug,其表达的意思是,若勾选则表示该配置为Debug工程,若不勾选则表示该配置为Release工程,与第一列的配置名称是啥,没有半毛钱关系。早些天这里是我误解的一个关键因素是,对第五列Debug的操作会画蛇添足地相应改变第一列的名称。
在 VS2015 + Qt VS Tools 2.0.0 下,使用上图向导中的默认配置,项目Debug和Release模式下都会产生同样的如下默认配置:
//C/C++ - 常规 - 附加包含目录%(AdditionalIncludeDirectories);$(Qt_INCLUDEPATH_);//连接器 - 输入 - 附加依赖项%(AdditionalDependencies);$(Qt_LIBS_)//连接器 - 常规 -附加库目录
$(Qt_LIBPATH_);%(AdditionalLibraryDirectories)
需要注意的是,在 VS2017+Qt VS Tools For 2017 环境下,使用上述Qt项目创建向导时,存在些小bug,具体请参见,在 《IDE/VS2017社区版安装+Qt部署+旧项目迁移》 中的部分说明。如果你的IDE下没有自动生成上述配置,可以尝试关闭并重启项目,修改Configuration名称等方案;当然你也可以使用最原始的方法,参照上述样子手动添加。
其中Qt_LIBS_会依据配置的Qt Modules自动展开为关联的lib动态库导入文件,下图为一个具体的简单项目中Qt_LIBS_宏定义截图:
其值为,
以同样方式查看 Qt_INCLUDEPATH_ 宏定义为,
以同样方式查看 Qt_LIBPATH_ 宏定义为,
常见编译错误
LNK2019
错误 LNK2019 无法解析的外部符号 “public: void __cdecl CPublishProxy4Qt::SignalProcessToQtObserver(void *,void *,unsigned char *,unsigned int)” (?SignalProcessToQtObserver@CPublishProxy4Qt@@QEAAXPEAX0PEAEI@Z),该符号在函数 “xxx” 中被引用…
使用了信号槽,但却没有在类定义中增加 Q_OBJECT 宏定义,脱离了QtCreator后,更容易忘记啦,而且VS的报错并不明确。
Qt installation 错误
Qt VS Tools -> Qt Versions -> 其中设置的Version名称 (如下图的5.12.8 和 5.12.8_msvc2015_64)会在vs的工程文件.vcxproj中被引用。
实际在vcxproj文件中引用如下:5.12.8_msvc2015_64 ,可搜索。其配置路径为,项目-> 属性 -> Qt Project Settings -> Qt Installation 选项中,可以选择不同的Qt安装版本,如下图:
因此,如果不同开发者的开发环境中,上述配置若不一样,将导致编译异常。直接提示找不到编译器,大约提示如下:There’s no Qt version assigned to project 3DVMS.vcxproj for configuration Debug/x64. Please assign a Qt installation in ‘Qt Project Settings’.
未定义的标识符 “QWidget/QLabel…”
我在VS下新建了一个Qt动态库项目,将以前的一些代码类添加进去,编译的时候报错,提示我部分Qt的类未定义或无法打开头文件,举例:
错误(活动) 未定义标识符 “QAbstractButton” …
错误 C1083 无法打开包括文件: “QLabel”: No such file or directory …
错误(活动) 无法打开 源 文件 “QPushButton” …
在编辑器中,存在红色波浪下警示。但是,像QList、QString、QtCore/qglobal.h等都是不告警的。一开始没有发现什么规律。拿出一个正常的VSQt工程来,打开项目属性,在对比过程中发现:
新项目中,对Qt模块的引用只有Core,这才恍然大悟。将其他的gui、widgets模块也加进去后,问题得以解决。
LNK1181 无法打开输入文件
编译错误提示 LNK1181 无法打开输入文件“XXX_SDK.lib”
这里的 “输入” 是指 “项目属性 -> 连接器 -> 输入 -> 附加依赖项”,我们已经在上述项目中进行了lib名称(不带路径)的正确配置,如遇上述提示,可以如下操作:
P1(测试可行):在VC++目录 -> 库目录 添加 lib的路径信息
P2(测试可行:在项目属性 -> 连接器 -> 常规 -> 附加库目录 添加lib的路径信息
@note 我们在VS中进行的这些关于 “库” 的配置,均是针对lib的,至于DLL的路径,程序在运行时,操作系统会去按照自己的规则进行搜索和加载。更多关于VS集成开发环境使用本身的问题,请参照其他文章。
LNK2001 无法解析的外部符号metaObject
LNK2001 无法解析的外部符号 "public: virtual struct QMetaObject const * __cdecl QtClass::metaObject(void)const " (?metaObject@QtClass@@UEBAPEBUQMetaObject@@XZ)
情景复述,在VS2017下,资源树上的过滤器上右键 - 添加 - 新建项 - VC++ - Qt - Qt Class,
#pragmaonce#include<QObject>classQtClass:publicQObject{
Q_OBJECT
public:QtClass(QWidget *parent);~QtClass();};
编译时,却存在上述错误。好在我前几天在 xxx.vcxproj.filters 这个配置文件中发现了 QtMoc 和 ClInclude 这两种不同的包含头文件的方式,顺着这条路,分析如下:
开始我先去查看了moc中间文件,发现,虽然类中已经包含了Q_OBJECT 宏定义,但是却没有对应的moc文件生成,因此,找不到QtClass::metaObject实现也就不足为奇了。重新清理工程或重启VS并没有生效。打开xxx.vcxproj.filters文件可见,
其中 localcamera.h 是可以有对应的moc文件生成的,但是我新建的 qtclass.h 却不可以。观察可得,项目包含localcamera.h使用的是QtMoc标签,而包含qtclass.h使用的是ClInclude标签。我尝试着手动修改标签,测试可以生效。
那么,如何通过VS工具来修改qtclass.h的相关属性,使其使用QtMoc标签添加到项目中呢?在资源树 qtclass.h 文件上右键 ,选择属性,
如上所示,将项类型从 “C/C++ 标头” 修改成 “moc”,保存,可见,xxx.vcxproj.filters文件中对应部分会发生期望的改变。修改后,重新编译,可生成对应的moc文件,编译错误也随之消失。时间有限,这个问题,我并没有继续深究。
版权归原作者 大河qu 所有, 如有侵权,请联系我们删除。