qt 调试

警告和调试消息

  Qt自带4个向外写警告和调试文本的方法。可以把它们使用在如下目的:

  • qDebug():用于写自定调试信息的输出;
  • qWarning():用于报告程序中的警告和可恢复的错误;
  • qCritical():用于写关键错误信息和报告系统错误;
  • qFatal():用于退出前简要地描述致命错误消息。

  如果包含头文件,qDebug()可以当做输出流来使用。例如:

 qDebug() << "Widget" << widget << "at position" << widget->pos();

  在Unix/X11 and Mac OS X平台,Qt实现了将错误信息输出到stderr设备。在windows中,如果是一个控制台程序,这个信息将发送给控制台;否则就发送给调试器。你可以通过 使用qInstallMsgHandler()安装一个消息管理者来接管那些函数。

  如果设置了QT_FATAL_WARNINGS环境变量,打印完警告信息后,qWarning就退出。这让获取向后跟踪更方便了。

  qDebug和qWarning都是调试工具。它们都可以通过QT_NO_DEBUG_OUTPUT和QT_NO_WARNING_OUTPUT取消调试。

  当程序表现得十分奇怪时,QObject::dumpObjectTree()和QObject::dumpObjectInfo()调试方法将十分有用。可以使用对象名,也可以不用。

为qDebug()提供流操作符号

  你可以通过qDebug()为你的类实现流操作符号。这个类实现的流是QDebug。在QDebug中你需要知道的方法是space()和nospace()。它们都返回一个debug流;它们之间的区别是十分在每条记录中插入一个空格。如下是一个描绘2D坐标的类的例子:

 QDebug operator<<(QDebug dbg, const Coordinate &c)
 {
     dbg.nospace() << "(" << c.x() << ", " << c.y() << ")";

     return dbg.space();
 }

  在Creating Custom Qt Types 文档中,用源对象系统集成自定义类型被掩盖地更深。

     如果禁用的,在工程.pro文件里面写上 DEFINES += QT_NO_DEBUG_OUTPUT QT_NO_WARNING_OUTPUT

调试宏

  头文件QtGlobal包含一些宏定义和预定义。

  3个重要的宏定义:

  Q_ASSERT(cond):cond是一个布尔表达式,如果cond是false,写警告信息:ASSERT:'cond' in file xyz.cpp,line 234,并退出。

  Q_ASSERT_X(cond, where, what):cond是一个布尔表达式,where是位置,what是消息,如果cond是false,写警告信息:ASSERT failure in where: 'what', file xyz.cpp, line 234,并退出。

  Q_CHECK_PTR(ptr):ptr是一个指针。如果ptr是0,就写警告信息:In file xyz.cpp, line 234: Out of memory,并退出。

  这些宏对诊断程序错误非常有用。例如:  

 char *alloc(int size)
 {
     Q_ASSERT(size > 0);
     char *ptr = new char[size];
     Q_CHECK_PTR(ptr);
     return ptr;
 }

  如果编译过程中定义了QT_NO_DEBUG,Q_ASSERT(), Q_ASSERT_X(), and Q_CHECK_PTR()将什么也没有。基于这个原因,宏的参数不应该带有副加功能。下面是一个使用Q_CHECK_PTR不正确的例子:

 char *alloc(int size)
 {
     char *ptr;
     Q_CHECK_PTR(ptr = new char[size]);  // WRONG
     return ptr;
 }

  如果这段代码通过定义QT_NO_DEBUG来编译,Q_CHECK_PTR中的表达式将不被执行,alloc将返回一个未初始化的指针。

  Qt库包含成百个错误检查。当程序错误发生时,它将被打印出来。因此,我们建议你在开发基于Qt的软件时,使用Qt的调试版本。

常见问题(bugs)

  有个常见的错误需要在这里提到的是:如果在类定义中包含Q_OBJECT宏和运行源对象编译器(moc),但是忘记将moc生成的源代码连接到你要执行的对象代码中,你将得到混乱不堪的错误消息。任何与vtbl_vtbl__vtbl或者相关的错误都是由这个问题导致的。

你可能感兴趣的:(Qt)