Qt 难找的意料之外原因、崩溃原因及错误原因(持续更新)

Qt 难找的意料之外原因、崩溃原因及错误原因(持续更新)

这是一些容易令人没想到的崩溃或错误原因

序言意料之外原因removeWidget只是移除并没有删除该widget写容器之类的明明语法对,看着例子也对,偏偏就是写error: no matching member function for call to ???QPainterPath的isEmpty有坑,有MoveTo数据也是空QML的ListView,在移动项并滚动操作下,contentItem.y会负值QSqlDatabase: QSQLITE driver not loaded

崩溃原因双重容器的find如果找不到需要寻找的key值就直接调用会崩溃表格的item如果是空的调用text()等会崩溃表格的setCellWidget的小部件,二次setCellWidget后调用老部件会闪退表格的QAbstractTableModel模型继承重写后,data漏写返回值后崩溃ModbusRTU模式,正常调用Qt的QModbusRtuSerialMaster库时崩溃叉掉窗口立即崩溃main函数里运行第一条函数方法前就崩溃Expression: invalid comparatorMicrosoft C++ 异常: std::bad_alloc,位于内存位置std::shared_ptr调用某函数的虚函数崩溃(这是一条完全摸不着头脑的崩溃,看看即可,平时碰不上)Qt源码中QWindowsWindow::destroyWindow()里QWindowsContext::instance()为空崩溃在线程0中停止,因为:Exception at 0xbd00e596, code: 0xc00000005: write access violation at: 0xbd00e596, flags=0x0(first chance).QWidget: Cannot create a QWidget without QApplication

错误原因——VS2019 QT5.12 MSVC2017找不到源文件ShaderEffectSource: 'recursive' must be set to true when rendering recursively.error: /EHa: No such file or directoryimplicit instantiation of undefined template QList...C2665: "qHash": ??个重载中没有一个可以转换所有参数类型the following files have no write permissionsc1083: 无法打开包括文件:" ui_XXX .h": No such file or directoryLNK2001: 无法解析的外部符号 "public: virtual struct QMetaObject const *_thiscall...Cannot install type 'Dialog' into protected module 'QtQuick.Controls' version '2'待续

序言

这是一些我自己摔惨了,付出了大量时间才筛选发现的原因,其相对应的解决方案可能莫名其妙,但是对于碰到的人来说可能是刚刚好

意料之外原因

removeWidget只是移除并没有删除该widget

用QStackedWidget时,每次删除其子窗口时,用到了对象名,新的子窗口设置同对象名,结果其控件被接到了被removeWidget的窗口里。

void QStackedWidget::removeWidget(QWidget *widget)

//保险删除方式

QWidget *widget = ui->stackedWidget->widget(0);

ui->stackedWidget->removeWidget(ui->stackedWidget->widget(0));

delete widget;

注:QTableWidget里的cellWidget就是更改了,QTableWidget会自行删掉释放的。 其文档虽然写了,但是一般没人仔细看每一点。 .

写容器之类的明明语法对,看着例子也对,偏偏就是写error: no matching member function for call to ???

实际你写的这个函数有个const,所以当修改成员变量时就出了问题,因为这个容器没有这个const后缀的成员函数。 解决:要么绕开,要么通过const_cast< MyClass * >(ptr)强行控制,但后者不建议,或者用mutable声明变量 .

QPainterPath的isEmpty有坑,有MoveTo数据也是空

如果在这条路径中没有元素,或者唯一元素是MoveToElement,则返回true;否则返回false。 解决:可以采用path = QPainterPath();和if (path.elementCount() != 0)进行相应的清空和判断。 注:其文档虽然写了,但是一般没人仔细看每一点。 .

QML的ListView,在移动项并滚动操作下,contentItem.y会负值

个人遇到情况:QML的ListView,在项很多有滚动条的前提下,从第一个拖动并同时滚动滚动条到末尾放开移动,会大概率contentItem.y成了负值,contentY 和 originY加了值,但是显示列表又正常。 原因:Qt自身的bug! 解决:用到上述值的,用对应的抵消偏移。 .

QSqlDatabase: QSQLITE driver not loaded

原因:一开始使用时,一直提示上面这个,但是找不到哪里出的问题,然后打印QSqlDatabase::drivers,就打印出来了这个原因: QSqlDatabase: an instance of QCoreApplication is required for loading driver plugins 解决:在使用数据库之前先定义QCoreApplication 注:网上说的32位用了64位库的,和打包的sqldrivers文件夹下dll复制到exe所在目录都是可以一试的

崩溃原因

双重容器的find如果找不到需要寻找的key值就直接调用会崩溃

QMap testMap;

QMap doubleMap;

testMap.insert(3,3);

doubleMap.insert(1,testMap);

doubleMap.insert(2,testMap);

qDebug()<

最后一行秒崩,原因是因为找不到,所以返回了是个野指针,调用了野指针的后果你明白的。 解决方案:

qDebug()<

if (doubleMap.find(3) != doubleMap.end())

doubleMap.find(3).value;

else

...

用[ ]代替find( ).value即可,但这会没有对应key就自行添加,也可以直接判断find后的值是否正常能使用。 .

表格的item如果是空的调用text()等会崩溃

QTableWidget->item(row,col)->text();

上面这个秒崩,但是下面的不会,但写这个没什么意义。

QTableWidget->item(row,col);

自己一般设好值是不会的,但是如果在存在完全没设值的行使用序号排序会出现item为空指针的情况,因为空行被排序拉了上来,默认序号能排序 解决方案: 在前面加个判断

if(QTableWidget->item(row,col) == nullptr)

是空则不执行调用item的语句即可。 .

表格的setCellWidget的小部件,二次setCellWidget后调用老部件会闪退

表格->setCellWidget(Row,Column,部件1); 表格->setCellWidget(Row,Column,nullptr); 调用部件1,立即闪退,其实这个很容易理解。

帮助文档中setCellWidget的解释是再次调用时,会删除老部件,所以老部件成了野指针,自然就无法调用。

.cpp

QMap table_ProgressBar;

table_ProgressBar.insert(row,new QProgressBar);

table_ProgressBar.insert(row+1,new QProgressBar);

ui->tableWidget->setCellWidget(row,column,table_ProgressBar[row]);

ui->tableWidget->setCellWidget(row,column,nullptr);

//另一个函数调用

qDebug()<

可以看到,这个QProgressBar是处于QMap中的其中一个键值对,如果单纯通过setCellWidget删掉了这个QProgressBar,那么这个键值对的值会成野指针。 对于这个QMap的调用,只要会调用到row为键的值,就会闪退。 解决方案: ①、setCellWidget后不进行第二次部件置换,可以通过setVisible将其隐藏/显现; ②、第二次setCellWidget重新插入回来,然后就没影响了。

ui->tableWidget->setCellWidget(row,column,table_ProgressBar[row]);

ui->tableWidget->setCellWidget(row,column,nullptr);

table_ProgressBar.insert(row,new QProgressBar);

//另一个函数调用

qDebug()<

.

表格的QAbstractTableModel模型继承重写后,data漏写返回值后崩溃

如上,本人重写后,Qt::DisplayRole处理中,漏了,切记所有有返回值的都需要写好返回值情况。

QVariant CustomTableModel::data(const QModelIndex &index, int role) const

{

if (!index.isValid())

return QVariant();

switch (role)

{

case Qt::DisplayRole:

{

if (index.column() <= _confirm_column)

return _text_content.at(index.row()).at(index.column());

// 漏了_confirm_column < index.column()情况没处理

break;

}

case Qt::EditRole:

{

...

break;

}

default:

return QVariant();

}

// 此处该补上 return QVariant();

}

崩溃体现: 产生打印代码:

QPainter::begin: A paint device can only be painted by one painter at a time.

QPainter::setCompositionMode: Painter not active

QPainter::begin: A paint device can only be painted by one painter at a time.

QPainter::translate: Painter not active

QPainter::worldTransform: Painter not active

QWidgetEffectSourcePrivate::pixmap: Painter not active

QWidget::repaint: Recursive repaint detected

且崩的地方位于main.cpp里的 return a.exec();处 .

ModbusRTU模式,正常调用Qt的QModbusRtuSerialMaster库时崩溃

崩溃显示:

ASSERT failure in processQueue: "send timer active", file qmodbusrtuserialmaster_p.h, line 301

或者

ASSERT failure in processQueue: "response timer active ", file qmodbusrtuserialmaster_p.h, line 302

或者

ASSERT failure in processQueue: "unexpected state: ", file qmodbusrtuserialmaster_p.h, line 377

崩溃原因不明,BUG源于QModbusRtuSerialMaster这个类,但是Qt官方5.13修复了这个BUG。

所以从Qt5.8——Qt5.12都会存在这个BUG,可选的话升级版本即可。

如果不升的话,看运气,可能崩溃也可能不会崩,暂时没找到解决办法。 .

叉掉窗口立即崩溃

MainWindow w;

w.setAttribute(Qt::WA_DeleteOnClose);

w.show(); //叉掉会崩,因为在栈上的delete &w;会崩

MainWindow *w = new MainWindow();

w.setAttribute(Qt::WA_DeleteOnClose);

w.show(); //叉掉会自行删除

.

main函数里运行第一条函数方法前就崩溃

一般主要两个原因,第一个是存在全局对象,然后其构造函数做了什么导致的崩溃;第二个是第三方库没有配好,所以就崩了,想办法配好所有库就行 .

Expression: invalid comparator

std::sort的第三个参数,判断前两个参数时,如果相等,必须返回false,否则就会出现上面的崩溃情况。 .

Microsoft C++ 异常: std::bad_alloc,位于内存位置

该原因是因为内存爆了,没有多余内存可以申请了

我给出我这犯错的示例,可以借鉴一下自己是否出现同样问题

QVector< uint8_t > data(5000);

for (uint8_t i = 0; i < 5000; ++i)

{

data.append((i % 200));

}

看出什么问题没?uint8_t限制了最大也只有255,255+1=0,所以i永远也到达不了5000的限制,所以data容器重复申请内存直至没有空间申请为止。

改为uint32_t、uint16_t或者int之类的最大值大于限定值即可。 .

std::shared_ptr调用某函数的虚函数崩溃(这是一条完全摸不着头脑的崩溃,看看即可,平时碰不上)

环境:Qt5.14.2+MSVC2017 64bit(VS2019) CONFIG += c++14

class AA

{

public:

AA(){qDebug() << __FILE__ << __LINE__ << __FUNCTION__;}

virtual ~AA(){qDebug() << __FILE__ << __LINE__ << __FUNCTION__;}

virtual void print(){qDebug() << __FILE__ << __LINE__ << __FUNCTION__;}

};

调用处:

std::shared_ptr< AA > b;

b.reset(new AA);

b->print(); //崩溃处

崩溃显示:about() has been called

原因:未知,且目前只在我公司电脑会出现该情况 解决方法:

使用VS则正常运行;将AA名换成任意其他名称则正常运行;~AA()或者print()任一前面删去virtual则正常运行。 .

Qt源码中QWindowsWindow::destroyWindow()里QWindowsContext::instance()为空崩溃

tw->updateTransientParent();

}

}

QWindowsContext *context = QWindowsContext::instance();

if (context->windowUnderMouse() == window()) // 崩溃处,是因为context是空指针

context->clearWindowUnderMouse();

浅薄原因:我用Qt的插件方法写了一些插件,并将插件嵌进了MainWindow里,但MainWindow在关闭时没有及时删除,因为某些原因延后(单例),结果在上边此处崩溃了,应该是在QLibrary卸载插件后,影响了QWindowsContext::instance()的提前释放。

解决方法:将嵌入插件的所在界面在关闭窗口时一并释放,不能等static的对象释放时再释放。

解释:为什么是浅薄原因,因为解决方法是糊里糊涂试出来的,并非看明白原因,以后明白实际原因再回来写。 .

在线程0中停止,因为:Exception at 0xbd00e596, code: 0xc00000005: write access violation at: 0xbd00e596, flags=0x0(first chance).

原因:发生了访问违规或非法内存操作引起的,通俗来说就是访问空指针或者悬垂指针了。

自己遇到的情况:调试崩溃处崩在一个完全摸不着头脑的地方,即调用处的指针有效,怎么看都不是崩的地方,于是打印了下,才发现是更之前的地方出现的崩溃,根本不是实际崩溃处。

解决方法:本人是因为写了成员函数指针,但是是用class 类;前置,导致该成员函数指针存的根本不是我传进去的那个值,打印这个指针竟然是个’true’? 去掉前置,加入include "类.h"就好了。

解释:原因各种各样,无法概全,仅供参考其中一种情况。 .

QWidget: Cannot create a QWidget without QApplication

无具体原因,只要崩溃就会打印,需要自行排查和定位具体哪里崩 .

错误原因——VS2019 QT5.12 MSVC2017

找不到源文件

原本可以打开的项目文件现在竟然关于qt的都打不开,提示找不到源文件,比如:

#include

1、Qt库路径问题 在下方的提醒路径仔细看看!会发现这个路径和当前路径有些差别,这是因为我们因为某些原因改了路径或者其中一个路径名字,导致这个项目记录源文件路径的是记录以前的路径,和现在的路径不对。 2、VS+Qt的找不到源文件 “QWidget… 如果是新建的项目,则是缺少配置路径:

VS属性页-》Qt Project Settings-》Qt Installation的版本名字与你Qt Versions配置的版本名字不对VS属性页-》Qt Project Settings-》Qt Modules缺少模块选择VC++目录-》包含目录-》配置Qt的头文件路径:C:\Qt\Qt5.14.2\5.14.2\msvc2017_64\include;C:\Qt\Qt5.14.2\5.14.2\msvc2017_64\include\QtCore;…

如果是已经配置好的项目,在与同事一起写的过程中,某次update文件,出现的两报错:

E1696 无法打开源文件"QObject" MSB4181:"QtRunWork"任务返回了false,但未记录错误

解决方案则是单纯的缺少文件或者少删除了文件,项目没有相同配置好。 看起来很扯,这和找不到源文件有啥关系,可偏偏我本人就是因为这个原因找了一下午,然后突发奇想让同事重新上传一次缺漏的文件就成了。 .

ShaderEffectSource: ‘recursive’ must be set to true when rendering recursively.

此错误解决方法查自于:半夏微凉半夏殇 缺了layer.enabled: true和layer.effect: .

error: /EHa: No such file or directory

今天又让我逮到一个恶心我又死活查不到为什么的错误,是使用Qt的异常处理时配置出现的。

//配置方法:

pro

win* {

QMAKE_CXXFLAGS_EXCEPTIONS_ON = /EHa

QMAKE_CXXFLAGS_STL_ON = /EHa

}

CONFIG += exceptions

使用:

QT_TRY {

int i=0;

int j=10/i;

}QT_CATCH(...){

qDebug() << "Error";

}

原因很简单,就是MinGW不支持,要用MSVC编译运行才行。 .

implicit instantiation of undefined template QList…

implicit instantiation of undefined template Q容器名啥的

其实就是少了对应头文件,加上就行,比如

#include //加上就行

implicit instantiation of undefined template QMap< int, QString > map;

.

C2665: “qHash”: ??个重载中没有一个可以转换所有参数类型

在这感谢sky20080101的博客,是在他那里找到的原因

QSet的类型,如果是普通数据类型(重载里存在的类型)或者指针,就可以直接正常使用QSet。

但是如果

QSet< AA > test;

AA a;

test.insert(a);

这样会报错的,因为AA并没有使用qHash”注册“过,QSet实际使用QHash实现的 解决方案: 在使用地方定义一个qHash就行,注意是在同一命名空间里,也要注意其他include本文件的容易重定义问题

uint qHash(const AA &a, uint seed = 0)

{

/* 只要能显示AA类型的独特id就行,使其在QSet里和其他的判断不是同一个 */

return qHash(a->name(), seed);

}

只是单纯的用qHash一般都能满足大多数要求了,如果还有关于"=="的错误,就需要自定义类AA补写个operator == .

the following files have no write permissions

在这感谢南方星的博客,是在他那里找到的原因

修改了某些路径信息后,比如修改了pri和文件夹的名称后,有一些的没保存,在代码区的上方document下拉框选择里,会有原路径的文件未保存,但是因为路径改了又保存不了显示加个黑色的锁,但是要编译就得保存弹出了上面的一个对话框显示那些文件,成了死循环。 解决方案: 在document下拉框里那些加了黑色锁的文件右键close掉即可。 .

c1083: 无法打开包括文件:" ui_XXX .h": No such file or directory

此处的原因大多两种,其他暂时没碰到,一是没有被编译到,可以 构建-》清理项目 ,清掉本项目的那些qmake出来的,然后qmake一下,再编译即可。

第二种是我这种,修改了含ui的文件名,然后" ui_XXX .h"就找不到了,上述的方法也没效果。 解决方案: 将h,cpp里将所有修改前的名称类修改成修改后的名称,ui的则修改objectName,这个ui不会自动改 .

LNK2001: 无法解析的外部符号 "public: virtual struct QMetaObject const *_thiscall…

LNK2001: 无法解析的外部符号 "public: virtual void *_thiscall **::qt_metacast(char const *)… LNK2001: 无法解析的外部符号 "public: virtual int __thiscal **::qt_metacall… 原因: 1、测试时在main.cpp里直接写了个继承QObject的,还加上了Q_OBJECT宏,Qt无法生成moc_main.cpp,所以只要放到别的文件就行。 2、没有加上Q_OBJECT 3、没有写#include < QObject> .

Cannot install type ‘Dialog’ into protected module ‘QtQuick.Controls’ version ‘2’

Warning: (2024-07-16 12:19:59 879) file:///.../QtQuick/Controls.2/qmldir -1 file:///.../QtQuick/Controls.2/qmldir: plugin cannot be loaded for module "QtQuick.Controls": Cannot install type 'VerticalHeaderView' into protected module 'QtQuick.Controls' version '2'

Warning: (2024-07-16 12:19:59 882) -1 : Cannot install type 'HorizontalHeaderView' into protected module 'QtQuick.Controls' version '2'

Warning: (2024-07-16 12:19:59 885) -1 : Cannot install element 'SplitHandle' into protected module 'QtQuick.Controls' version '2'

Warning: (2024-07-16 12:19:59 889) -1 : Cannot install type 'SplitView' into protected module 'QtQuick.Controls' version '2'

Warning: (2024-07-16 12:19:59 892) -1 : Cannot install element 'Overlay' into protected module 'QtQuick.Controls' version '2'

Warning: (2024-07-16 12:19:59 895) -1 : Cannot install type 'MenuBarItem' into protected module 'QtQuick.Controls' version '2'

Warning: (2024-07-16 12:19:59 899) -1 : Cannot install type 'MenuBar' into protected module 'QtQuick.Controls' version '2'

Warning: (2024-07-16 12:19:59 902) -1 : Cannot install type 'ActionGroup' into protected module 'QtQuick.Controls' version '2'

...

原因: Qt环境没有正确配好 解决方案: 将环境变量的有关Qt的路径去除,然后重新配置好Qt的环境变量

待续

暂时只碰到这些容易忽略的崩溃或错误原因,其他碰到了再添加上

相关推荐

猱的解释
英国365网站最近怎么了

猱的解释

07-06 👁️ 9962
如何贴窗花更合适
英国最大赌博365网站

如何贴窗花更合适

07-18 👁️ 4575
碛月的意思
英国365网站最近怎么了

碛月的意思

07-04 👁️ 706