在C++、Qt软件开发过程中,常常遇到一些编译错误或警告;本文将VS2019、Qt5.12.10和QGis3.16.10的二次开发过程常见的问题做了整理,供大家参考,也便于日后查阅。该内容分为四部分:VS+Qt环境搭配、VS编译常见问题、Qt常见问题、QGis二次开发常见问题。(转载请注明出处:https://www.cnblogs.com/1024bytes/p/15464404.html)


一、VS创建Qt项目
      1、安装VS2019或VS2017,编译器原则上是越新越好(此贴发布时VS2022测试版已经发布,没试过有啥新功能),VS选择需要的组件和编译器,不用全选。
      2、Qt用5.12版中最新的,我用的是Qt5.12.10(Qt5.15是向Qt6过渡的产品),组件也是根据需求选择。
      3、VS中要安装Qt Visual Studio Tools,菜单栏依次选择“扩展”-“管理扩展”-“联机”-“Visual Studio Marketplace”,在右侧搜索“Qt”,选择“Qt Visual Studio Tools”,点击下载,安装界面弹出后,关闭VS,安装完成。重启VS,可在该菜单栏看到菜单“Qt VS Tools”。在该菜单下选择“Qt Versions”配置Qt路径;创建界面可由此菜单选择“Luanch Qt Designer”。
      4、新建项目->Visual C++/跨平台->Qt,选择Qt Widgets Application。

二、VS编译常见问题
Q: “M_PI”: 未声明的标识符
A: 程序中头文件的选择,要选择math.h头文件,在cmath文件中是没有对M_PI 的定义的(现在的cmath中对M_PI好像已有定义)。选择“项目”——>”XXX属性"——>配置属性——>C/C++——>预处理器——>预处理器定义,将“_USE_MATH_DEFINES”添加进去。

Q: 源代码字符编码问题: Warning C4819 该文件包含不能在当前代码页(936)中表示的字符,请将该文件保存为 Unicode 格式以防止数据丢失
A: 光标定位到该文件,选择菜单里的高级保存选项utf-8 with signature,带签名的65001,高级保存选项添加方式见https://www.cnblogs.com/daxueba-ITdaren/p/7272210.html

Q: Warning MSB8004: Output Directory does not end with a trailing slash
A: 设置的目录参数不是以反斜杠结束的目录名称,属性→General→Output Direction里加上反斜杠。

Q: 不允许指针指向不完整的类类型
A: 添加该类类型的头文件,如QStatusBar

Q: LNK1169 找到一个或多个多重定义的符号
A: 多次引用头文件,比如所处位置为.h里,改到.cpp里。哪个文件需要,放在哪个文件里,不需要的不要放在.h里

Q: 引用头文件后遇到无法解析的外部符号
A: link里加入lib,目录要添加lib所在目录

Q: Error LNK2019: unresolved external symbol WinMain referenced in function "int _cdecl invoke_main(void)"
A: 右键点击项目,属性→linker→System,修改subsystem。函数入口为main的,选择console;另一种解决办法见QGis二次开发常见问题。

三、Qt常见问题
Q:无法打开包括文件: “QDomDocument”、“QSvgRenderer”之类的问题: No such file or directory
A:C++的包含目录要包含问题模块所处的路径,如QtXml、QtSvg,打印支持还要添加QtPrintSupport、网络QtNetwork

Q: svg的图片为什么在工具栏不显示、编译成功运行不起来?
A: 复制Qt的plugins目录下的imageformats文件夹到程序运行目录;依赖的Qt的dll也要拷到运行目录里(windeployqt了解一下)。

Q:This applicationfailed to start because no Qt platform plugin could be initialized
A: 复制Qt的plugins目录下的platform文件夹到程序运行目录;依赖的Qt的dll也要拷到运行目录里(windeployqt了解一下)。

Q: 信号SIGNAL和槽SLOT如何连接?
A: 如果一个信号不多个槽相联系的话,那么,当这个信号被发射时,与之相关的槽被激活的顺序将是随机的。当点击菜单时,动作触发了多次,这跟connect有关,手动和内部自动重复。connect的几种写法如下:

QMenu* fileMenu = new QMenu;
fileMenu = this->menuBar()->addMenu("File");
actionOpenFile = new QAction("Open", this);
// connect 方式一:SLOT参数传actionOpenFile的默认触发槽函数on_openFileAction_triggered()
connect(actionOpenFile, SIGNAL(triggered(bool)), this, SLOT(on_openFileAction_triggered())); /**
* connect 方式二:手动设置object name, 然后再显式调用connectSlotsByName()。
* 若由designer自动创建的连接,代码加了connectSlotsByName则会触发两次,因此不要在代码里再连接信号槽。
* 代码创建的部件,可以自定义槽函数void on_<窗口部件名称>_<信号名称>_(<信号参数>),用下面方法连接
* actionOpenFile->setObjectName("actionOpenFile");
* QMetaObject::connectSlotsByName(this);
**/ QgsLayerTreeViewDefaultActions* actions = QgisDemo::instance()->layerTreeView()->defaultActions();
connect(actions->actionRemoveGroupOrLayer(), SIGNAL(triggered(bool)), QgisDemo::instance(), SLOT(slot_updateAppTile()));//connect用法1
//connect(actions->actionRemoveGroupOrLayer(), &QAction::triggered, QgisDemo::instance(), &QgisDemo::slot_updateAppTile);//connect用法2

Q: 一个信号和两个或多个槽函数连接时,由于先后顺序随机性,如何作调整?
A: 将其中一个槽函数里写入非阻塞的延迟处理,调用processEvents会让Qt继续处理线程所在的消息队列中未处理的消息,直到消息队列中没有消息可以处理。当进行长时间的操作的时候可以调用此函数(比方说拷贝文件)。这个函数可能和我们要使用msleep的本意有差别,但是使用它可以在svalue时间内处理events,从而达到类似sleep的目的。可参考https://www.cnblogs.com/bokeyuan-dlam/articles/6794911.html,代码如下:

Time dieTime = QTime::currentTime().addMSecs(svalue);
while( QTime::currentTime() < dieTime )
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);

Q: QwtPlot是qwt6的绘图类,第三方库,如何用?
A: linker里添加qwt.lib,C++包含目录里加入对应的include文件qwt6。

Q: Uic'ing xxx.ui系统找不到指定的路径
A: 问题原因是工程引用了环境变量”QTDIR”,但是用户安装QT后没有配置该环境变量。方法一:在系统环境变量里添加QTDIR,重新启动VS。方法二:右键点击xxx.ui文件,选择属性,将命令行和附加依赖项的uic.exe的路径改成qt目录的绝对路径。注意生成的ui_xxx.h路径,可在C/C++附加目录中添加进去,否则头文件找不到。

四、QGis二次开发常见问题
注意:QGis3.16是基于Qt5.11.2编译的,如果开发用Qt5.12版本,库也需要同样版本重新编译一下。

Q: 若用Qt Creator作二次开发构建,如何配置库引用?
A: 在pro文件中加入以下代码:

INCLUDEPATH += "C:/OSGeo4W64/apps/qgis/include"
INCLUDEPATH += "C:/OSGeo4W64/include" LIBS += -L"C:/OSGeo4W64/apps/qgis/lib" -lqgis_core -lqgis_gui
LIBS += -L"C:/OSGeo4W64/lib" -lgdal_i DEFINES += CORE_EXPORT=__declspec(dllimport)
DEFINES += GUI_EXPORT=__declspec(dllimport)

Q: VS提示LNK1104: 无法打开文件“qgis_core.lib”
A: 将依赖库拷到运行目录

Q:VS构建需要的依赖库
A:(1)C/C++常规->附加包含目录:
D:\QGIS\OSGeo4W64\include
D:\QGIS\OSGeo4W64\apps\qgis-ltr\include
D:\Qt5\5.12.10\msvc2017_64\include\QtXml
     (2)链接器->常规—>附加库目录:
D:\QGIS\OSGeo4W64\apps\qgis-ltr\lib
D:\Qt5\5.12.10\msvc2017_64\lib
     (3)链接器->输入->附加依赖项:qgis_core.lib qgis_gui.lib qgis_analysis.lib(根据需求添加,如果app里需要的部分头文件和源文件拷贝过来的话,qgis_app.lib不需要;否则也要加上)

Q: 2.x版本的一些示例中的类在3.x中找不到头文件
A: 参考官网资料,3.x版本作了一些删改与合并,比如QgsProject替代qgsmaplayerregistry,3.x前后API变动记录详见https://qgis.org/api/api_break.html

Q: 如何取消地图工具状态?
A: 切换回到原来的无地图工具状态,解决思路就有了。先获取到当前的地图工具,然后 unset 掉它,并不设置新的工具,就可以了。代码如下:

QgsMapTool *lastMapTool = m_mapCanvas->mapTool();
m_mapCanvas->unsetMapTool( lastMapTool );

Q: qgis_gui项目中出现未定义的标识符 "QWebElement"
A: 附件目录添加D:\QGIS\OSGeo4W64\apps\Qt5\include\QtWebKit;但是由于Qt5.6起弃用这个类,变换了新类,因此要么从源码解决这个问题,要么cmake在build源码时取消WITH_QTWEBKIT;要么注释掉报错函数关于QWebElemen类的内容,并在qgismaptip.cpp文件开头注释掉WITH_QTWEBKIT:

//#if WITH_QTWEBKIT
//#endif

Q: error LNK2019: 无法解析的外部符号 WinMain,MSVCRT.lib
A: 方法一:见上方的“VS常见问题”;方法二:由于QGis新建项目是控制台应用程序,而程序通过的是WinMian(及windows入口函数),因此需要作下处理:在“qgis_core项目”->“属性”->“连接器”->“输入”附加依赖项中,debug版本添加D:\Qt\Qt5.12.10\msvc2017_64\qtmaind.lib,release版本则添加qtmain.lib。

VS2019、Qt5.12及QGis3.16开发常见问题汇总的更多相关文章

  1. VS2017+QT5.12.10+QGIS3.16环境搭建及开发全流程

    题记:大力发展生产力,助力高效采集.(转载请注明出处https://www.cnblogs.com/1024bytes/p/15477374.html) 本篇随笔分为五个部分: 一.获取QGIS3.1 ...

  2. WEB前端开发常见问题汇总

    1.web扫码登录怎么实现,思路? 步骤 WEB平台 手机 第1步 生成二维码 第2步 (ajax监控后台) 扫码 第3步 (ajax监控后台) 确定(后台异步通知WEB平台) 第4步 AJAX发现状 ...

  3. 【全网首发】使用vs2017+qt5.12.4编译64位debug和release的qgis3.4.9

    一.摘要: 搜索网络没有发现一篇文章完整的介绍如何编译qgis3.4.x的debug版本,官方的指导也长时间不再更新. 所以前前后后花了4天搞定qgis的debug编译,并成功运行,废话不多说,直接上 ...

  4. Qt5.12.2开发Android环境搭建

    Qt-Android开发环境概要qt-opensource-windows-x86-5.12.2----armv7jdk-8u201-windows-x64android-ndk-r18b-windo ...

  5. 麒麟系统开发笔记(二):国产麒麟系统搭建Qt开发环境安装Qt5.12

    前言   开发国产应用,使用到银河麒麟V4,V10,本篇以V10记录,参照上一篇可安装V4.V7.V10三个版本,麒麟V4系自带了Qt,麒麟V10没有自带Qt,需要自己编译搭建环境.   银河麒麟V1 ...

  6. 麒麟系统开发笔记(三):从Qt源码编译安装之编译安装Qt5.12

    前言   上一篇,是使用Qt提供的安装包安装的,有些场景需要使用到从源码编译的Qt,所以本篇如何在银河麒麟系统V4上编译Qt5.12源码.   银河麒麟V4版本   系统版本:   Qt源码下载    ...

  7. XBOX ONE游戏开发常见问题

    XBOX ONE游戏开发常见问题 终于弄懂这个在Unity的sdk在Account Picker切换账号的机制了,一个手柄注册一个账号,在游戏里面的时候,只有另外一个手柄选择自己的账号,系统的Acti ...

  8. Ubuntu18.10下安装Qt5.12过程记录

    首先你得先安装Ubuntu操作系统(我是在VMWare14中安装的Ubuntu18.10版本). 阿里镜像:https://opsx.alibaba.com/mirror 我这里下载的文件为:ubun ...

  9. VueJS 开发常见问题集锦

    由于公司的前端开始转向 VueJS,最近开始使用这个框架进行开发,遇到一些问题记录下来,以备后用. 主要写一些 官方手册 上没有写,但是实际开发中会遇到的问题,需要一定知识基础. 涉及技术栈 CLI: ...

随机推荐

  1. VUE001. 拖动div盒子(自定义指令v-directives)

    拖动div是一个逻辑很简单的需求,监听容器的鼠标按下松开的事件,执行函数通过DOM改变标签的CSS偏移量. 在VUE构建的项目中,通过标签的 @mousedown 和 @mouseup 赋予行为事件, ...

  2. 使用Apache poi来编写导出excel的工具类

    在JavaWeb开发的需求中,我们会经常看到导出excel的功能需求,然后java并没有提供操作office文档的功能,这个时候我们就需要使用额外的组件来帮助我们完成这项功能了. 很高兴Apache基 ...

  3. MySQL数据库初体验

    一.数据库的基本概念1.数据(Data) 描述事物的符号记录 包括数字,文字,图形,图像,声音,档案记录等 以"记录"形式按统一的格式进行存储 2.表 将不同的记录组织在一起 用来 ...

  4. JAVA安全基础之代理模式(一)

    JAVA安全基础之代理模式(一) 代理模式是java的一种很常用的设计模式,理解代理模式,在我们进行java代码审计时候是非常有帮助的. 静态代理 代理,或者称为 Proxy ,简单理解就是事情我不用 ...

  5. git config 选项

    git config  --global -- global 写入选项:写入全局的 ~/.gitconfig 文件而不是版本库的 .git/config,如果 ~/.gitconfig 文件不存在,则 ...

  6. 关于 CLAHE 的理解及实现

    CLAHE CLAHE 是一种非常有效的直方图均衡算法, 目前网上已经有很多文章进行了说明, 这里说一下自己的理解. CLAHE是怎么来的 直方图均衡是一种简单快速的图像增强方法, 其原理和实现过程以 ...

  7. mysql将语句写入表中

    使用create table语句即可 CREATE TABLE membertmp (select a.* from member as a where a.phone <> '' and ...

  8. 微信小程序view不能换行 text实现转义换行符

    在html中可以直接使用<br />换行,但是小程序wxml中使用<br />无效,可以换成\n Page({ data: { title: '至少5个字\n请多说些感受吧' ...

  9. Linux系列(21) - 光盘、U盘挂载

    挂载光盘 mount命令.umount命令 step-1 建立挂载点 原理:相当于建立盘符,建个目录读取光盘内容 命令:[root@localhost ~]# mkdir /mnt/cdrom/ 备注 ...

  10. Selenium多浏览器处理 (Chrome/Firefox/IE)

    测试用例文件:test_selenium/test_hogwarts.py 使用pytest框架 定义一个变量,通过外部传入变量,确定使用哪个浏览器 browser = os.getenv(" ...