原文链接:http://blog.csdn.net/oLuoJinFanHua12/article/details/100667592
有道词典导致Qt程序卡死的问题我已经发现了一段时间,之前以为是自己程序的问题,后面多方验证才发现这个问题是我更新到Qt5.12后产生的。
下面是该bug的重现条件:
1.打开有道词典,将屏幕取词开关打开
2.在自己的程序中添加一个QTreeView或者QTreeWidget,并且添加一些数据
没错,这个bug主要是在QTreeView或QTreeWidget上引发,其他控件我还没有发现存在该问题。我这里就使用Qt的帮助文档软件来测试:
3.将鼠标放到上面的红色框选区域中停顿1秒左右
软件卡死。打开任务管理器可以看到Qt帮助软件的内存正在疯狂增长,并且CPU居高不下:
其实,有人已经向Qt反馈了该问题https://bugreports.qt.io/browse/QTBUG-77974,不过目前这个问题还未解决。Qt的开发人员表示会在Qt5.13.2和Qt5.14上解决该问题,不过在此之前我们可以临时解决一下该问题,以下是我提供的一个临时解决方案。
临时解决方案
通过翻阅源代码发现,该问题引起的位置位于Qt底层windows部分的uiautomation模块中,而通过消息分析发现引起该问题的Windows消息为WM_GETOBJECT。修改uiautomation内的代码比较困难,并且需要编译Qt源代码,太过麻烦,因此,我选择屏蔽掉WM_GETOBJECT消息,这里是关于WM_GETOBJECT的解释https://docs.microsoft.com/zh-cn/windows/win32/winauto/wm-getobject
以下是临时解决方案的代码,写在main.cpp中即可:
#include <qt_windows.h>
#include <QApplication>
#include <QTreeWidget>
#include <QAbstractNativeEventFilter>
//QTBUG-77974
class MyFilter : public QAbstractNativeEventFilter
{
public:bool nativeEventFilter(const QByteArray& eventType, void* message, long* result) override{MSG* msg = (MSG*)message;if (msg->message == WM_GETOBJECT)return true;return false;}
};int main(int argc, char *argv[])
{QApplication a(argc, argv);a.installNativeEventFilter(new MyFilter);QTreeWidget w;w.exec();return a.exe();
}
过滤掉WM_GETOBJECT之后应用程序不会再被有道词典卡死了,等官方解决该问题后就可以删掉这段代码了。
Node: 实测Qt5.13.2版本下已解决该问题