目录
运行环境
IDE:Microsoft Visual Studio Community 2019, 16.11.15
Qt:5.12.5_msvc2017, 32bit
OS:Windows 10 家庭版,21H2
背景说明
我们在使用 VS 开发 Qt 程序时,经常会遇到无法观察 Qt 类型变量值的问题。网上有类似的解决 QString 等对象的方法,如VS调试状态下查看QString等QT变量_阿莫西林夹馍的博客-CSDN博客,不过像 QMainWindow、QWidget 等对象监控起来还是有些不方便,网上也没有搜到解决方法。调试Qt自带例子 addressbook ,在main.cpp 里查看 mw 变量,看到的主要就是一系列地址,用处不大。如果调试时想看下窗口的 caption 怎么办?
Qt 类的封装
-
QObject、QWidget、QMainWindow 的继承关系如下图所示。它们内部都有一个对应的“Private类”,指向内部的参数,即:QObjectPrivate、QWidgetPrivate、QMainWindowPrivate,而且Private类都是在cpp文件中定义的,因此它们的定义其实被“隐藏”了,外部是不可见的。
-
深入QObject可以知道Private类对象对应的是d_ptr,一个智能指针对象。
-
那 QMainWindow 是怎么访问 d_ptr 的?用 Q_D 宏。
-
Q_D 宏的定义,先调用d_func(),再调用qGetPtrHelper()获取d_ptr指向的对象,并已经完成类型转换,QMainWindow直接获得QMainWindowPrivate对象。
-
看到一个 有意思的地方,用 operator->() 访问智能指针内部保存的裸指针。下面我们就试试这个运算符。
用VS监视对象
-
VS变量监视器直接访问d_ptr,得到的是QScopedPointer对象,不是我们要的;
-
加上运算符,VS识别到了实际的类型,太棒了!
找到 caption 了,记住这串代码,后面有用。注意:类型里还有动态库名称的限制。
(*((Qt5Widgetsd.dll!QWidgetPrivate*)&(*((Qt5Widgetsd.dll!QMainWindowPrivate*)this->d_ptr.operator->())))).extra->topextra->caption
使用 natvis 文件
Natvis文件已经替换autoexp.dat文件来自定义监视变量,可以在项目中添加natvis文件,也可以更改用户级别的natvis文件。
-
在项目中使用natvis文件
-
添加natvis文件
-
编辑natvis文件
<?xml version="1.0" encoding="utf-8"?> <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> <Type Name="QMainWindow"> <DisplayString>{{ caption = {(*((Qt5Widgetsd.dll!QWidgetPrivate*)&(*((Qt5Widgetsd.dll!QMainWindowPrivate*)this->d_ptr.operator->())))).extra->topextra->caption} }}</DisplayString> </Type> </AutoVisualizer>
因为natvis文件是xml格式的,所以“>”、“<”、“&”等要用实体引用。
-
-
使用用户级别natvis
-
直接编辑C:/Users/[user name]/Documents/Visual Studio 2019/Visualizers下的natvis文件
-
效果
可以显示 caption 信息了! 其他更多功能,就自由发挥啦。
参考文献
原创文章,作者:Carrie001128,如若转载,请注明出处:https://blog.ytso.com/277956.html