目录
工具开发
界面类继承某自定义界面类时,出现布局混乱或者所有控件集中在左上角?
在继承自定义界面之后,以诸如 on_xxx_clicked() 模式设计的槽函数失效了?
使用pugi接口取出文本数据后,为什么该变量无法进行字符串比较?
在使用Pugi接口的时候为什么指令正确,但是无法通过编译器编译?
插件(Qt)开发
在使用QLabel、QGroupBox等控件时出现字体显示不全或遮掩?
VisualStudio IDE
启动调试遇到帧不在模块?
报错异常中,出现 0XC0000005:读取位置0X0000000000000000时发生访问异常?
使用static_cast将MainWindow (类型为QWidget) 转换成其他数据类型,出现空指针?
在进行调试的时候,出现“未加载符号文件”?
在打开应用时出现“无法找到入口”的报错?
编译时可通过单击索引到头/cpp文件,但编译器无法检测到该文件(C1083)?
编译时出现缺少*.lib 又或*.dll的情况?
编译报错问题
C2011 编译时出现“xx类型重定义”?
C2280 “xxxxx”尝试引用已删除的函数 报错?
C2039 xx不是QMetaTypeId的成员?
MSB6006 用CMake生成代码后出现”cmd.exe”已退出?
LNK2019 LNK2001 无法解析的外部符号?
本文共计5252字,预计阅读时间15分钟
工具开发
界面类继承某自定义界面类时,出现布局混乱或者所有控件集中在左上角?
原因:这类原因与开发过程中使用到的ui.setupUi() (或者ui->setupUi() )指令有关,在设定Ui界面我们默认会直接使用this,即当前类的界面对象。而在继承时,界面的实现类会可能会对界面的排布进行重设定,所有控件的排布会根据一个以默认参数生成的Widget对象进行相对排布设置。而在QDesigner工具下设计的Ui界面的窗体排布一般是经过调整修改过的(例如窗体长、宽又或者布局等),最终造成了这类问题。
解决方法:通过在代码层新建一个Widget对象,用来创建符合默认参数的Widget对象,并将Ui界面放在该控件上,从而解决该类问题。代码片段如下
QWidget * widget = new QWidget(); //欲创建的自定义界面类 _ui = new Ui::XXxxxx(); _ui->setupUi(widget); SetContentWidget(widget); //必须通过如下指令对窗体的标题进行设定 //setWindowTitle(QString::fromLocal8Bit("欲设定的窗体名称")); |
在继承自定义界面之后,以诸如 on_xxx_clicked() 模式设计的槽函数失效了?
原因:首先,我们要搞清楚槽函数的绑定监听机制,在使用自定义界面类后,Ui界面实现类(这里为了举例,用HRxxxClass来表示)中有一段函数原本是ui->setupUi(this),this的指向是当前实现类的指针,槽函数在绑定监听时是默认绑定到当前实现类的,即HRxxxClass,而在设置主题时,生成的Widget控件对象在这里取代了XXxxxClass,但内部的槽函数绑定机制还是默认绑定在XXxxxClass类上,因此造成了这种现象。
解决方法:可以通过对底层绑定机制进行重写(对.moc文件进行修改)。但这里推荐一种普遍、简单的方法,即使用connect函数来对建立控件与函数之间的连接,代码片段如下
connect(Component,&Component::event,this,&XXxxxClass::FunctionUDesigned()); //connect有三种写法,这是其中一种; |
使用pugi接口取出文本数据后,为什么该变量无法进行字符串比较?
原因:Pugi在取出值时用到的最终指令是 xx.value(),取出的数据类型是 const char * ,而char *类型的逻辑比较是用C语言中的strcmp()函数(印象中是这个),如果在比较中直接使用 == 比较符来进行判断,显然是不可行的,因为没有对该操作符进行重载(C语言中)。故造成这种现象。
解决方法:可以通过pugi接口下的xx.as_string()指令来将该数据进行转换,然后通过 == 逻辑比较符来进行判断,亦可通过QString(xx.value())将其转换成QString型文本进行比较。代码片段如下
QString(xx.attribute("xx").value()) == QString("xxx") |
在使用Pugi接口的时候为什么指令正确,但是无法通过编译器编译?
原因:一般出现这种情况是因为指令中出现有中文字符。首先我们应当知道,中文字符一般是以GB2312、GB18030、GBK、Big5等形式进行编码,而在开发中,C/C++编译器(GCC, Clang, MSVC等)并不是以中文字符作为默认编译编码格式的,因此在编译时编码就出了问题,故出现此类现象。
解决方法:可以通过notepad、VSCode、VS代码保存对话框等,将该代码格式文件(*.h, *.cpp 等)统一转换成ASCII码然后保存。不过这个也可以通过修改编译器编码格式来进行解决,一般而言,在Linux (默认编码格式是UTF-8)环境下一般不会出现这类现象。
插件(Qt)开发
在使用QLabel、QGroupBox等控件时出现字体显示不全或遮掩?
原因:首先应当了解Qt控件中的显示受制于QSS样式表,而QSS样式表的设计模型参考于“盒子模型”,其中包含了诸多样式元素,包括:边距、边框、填充和实际内容等。由此当发现字体出现遮盖的情况下,大概率时因为文字在显示时存在边沿被其他控件遮盖,此时通过调整styleSheet即可解决这类问题。
解决方法:通过直接在QtDesigner中对控件中的styleSheet属性进行配置,例如 padding: 4px 将填充控件拓展至 4px 使得文字得以正确显示出来;或通过代码进行设置,例如
ui->你的控件->setStyleSheet(QString("padding: 4px")); |
VisualStudio IDE
启动调试遇到帧不在模块?
原因:一般是没有将链接器中的调试设置好,应当尝试进入项目属性页进行对链接器的设置。
解决方法:进入项目属性界面,选择链接器中的调试选项,单击“生成调试信息”中的“生成调试信息”,启用调试。同时在C/C++中的常规选项中,选中“调试信息格式”,并选择“用于编辑并继续的程序数据库“选项,输出调试信息。具体如下图所示。
注:保持输出目录路径与生成程序数据文件的目录路径一致。
报错异常中,出现 0XC0000005:读取位置0X0000000000000000时发生访问异常?
原因:造成这个问题是由于空指针报错,此时应当在代码层进行检查,排除是否存在生成“空对象”或者“空数据”的情况
解决方法:按住Ctrl键,用鼠标点击功能函数,定位对应的处理函数中去,对其中的代码进行分析排错,设立断点并监控堆栈调用,来定位问题所在点。
使用static_cast将MainWindow (类型为QWidget) 转换成其他数据类型,出现空指针?
原因:首先,出现这个问题是因为 static_cast 是一种强制转换方法,他会将QWidget强制转换成其他类型,而实际上,其他类型的类和QWidget之间有些属性是不一致的,且继承关系也不一致,所以很多属性在转换时会发生丢失。
在进行调试的时候,出现“未加载符号文件”?
原因:出现该问题是因为在调试模式下加载到了该动态库,但没有找到与之对应的*.pdb符号文件。
在打开应用时出现“无法找到入口”的报错?
原因:主要是 目标动态库版本不匹配(代码指令不匹配)或 当前项目调用方法有误,封装的动态库中存在函数指令或代码不符合调用规范。欲解决这类问题需要从调用该动态库的函数或者对调用的动态库本身进行修改。
解决方法:
对目标动态库编译项目进行更正,调整至与调用项目相同的代码规范然后进行重新编译输出。对调用该动态库的程序段进行检查,检查是否存在有“错误调用”、“错误的语法”、“错误的声明”等,对这些代码片段进行更正使其规范。
编译时可通过单击索引到头/cpp文件,但编译器无法检测到该文件(C1083)?
原因:一般出现这种情况是因为没有在附加目录中添加该文件的路径,导致编译器无法索引到对应文件。在这里拓展一个概念,在索引项目时,VS IDE会在缓存(内存)中加载好关联文件的路径,IntelliSense也会帮你智能地加载一些关联头/CPP文件。但是在编译的时候,编译器并不会把这些路径读取出来,需要通过手动,在附加目录中包含这个文件的引用路径才可以最终在编译阶段,按照给出的地址进行索引再到编译。另外,还需要注意同名复用的情况。
解决方法:在属性页中进行设置,需要进行修改的地方如下图所示:
编译时出现缺少*.lib 又或*.dll的情况?
没有在.sln(VS工程项目)中配置依赖库又或者附加目录,可以通过在工程项目的属性中添加附加库目录(这个主要是用来引用外部库的,即.lib文件),具体操作如下:
右击项目属性,找到‘附加库目录’
添加目标目录的路径(注意区分x64,x32)。
同时,在链接器中的高级选项中,也需要添加*.DLL相关的路径地址。
编译报错问题
C2011 编译时出现“xx类型重定义”?
原因:原因多是频繁引入、多次定义具有相同结构(同命名)的类或数据体。
解决方法:在编写头文件等定义数据结构或方法的文件时,通常采用#pragmaonce、#include、#ifndef、#define、#endif(除第一条指令外,标准开发上采用#ifndef->#define->#include->#endif的顺序)来定义头文件标识,这样便可以防止某个头文件中的宏多次被定义。从而解决该问题。
C2280 “xxxxx”尝试引用已删除的函数 报错?
原因:这个报错原因实际上与取址访存有关,在遇到这类情况时,通常是将目标类或数据结构等转换成智能指针的形式来处理,这样可以避免出现在另外一处调用类、数据类型或取出数据时出现“尝试引用已删除的函数”。(想一想类中是不是有析构函数?)
解决方法:通过代码std::make_shared<xxxx>(xxx)将目标类型转换成智能指针的形式。可以参照下列代码
std::shared_ptr<XXXXX> phaseDlg = std::make_shared<XXXXXX>(this); |
C2039 xx不是QMetaTypeId<T>的成员?
原因:没有注册对应的多元目标类型
解决方法:用宏Q_DECLARE_METATYPE()来注册目标类型。
Q_DECLARE_METATYPE(std::string); |
MSB6006 用CMake生成代码后出现”cmd.exe”已退出?
原因:
I.项目目录中没有引用到头文件
II.在拷贝头文件时是直接复制粘贴,而在工程项目文件(*.vcxproj)中并没有把文件路径给写入进去(也就是VS项目管理文件没有得到文件信息同步)
III.CMakeLists中配置参数设置错误,添加的头文件路径有误
V.若是Qt项目,一般是*.qrc资源文件中路径设置错误(要在qrc中配置好图标或其他资源的引用路径)
解决方法:对于1-2因素造成的cmd 已退出可以通过在VS中右键点击“已有项”来加入代码;而对于因素3可以重新配置好正确的参数,然后执行CMake生成程序将项目目录进行重新构建;对于因素4则是则是要确认好在通过Qt 资源编辑工具将*.qrc文件中的资源路径给配置正确,也可以通过文本编辑工具将文件打开,在面板中设置好路径参数。
LNK2019 LNK2001 无法解析的外部符号?
原因:所引用的头文件及调用的函数所在项目未编译输出至最新(代码不一致,DLL链接不上)
解决方法:找到所引用到的头文件/函数的所在项目,对其重新编译输出