Qt错误:Q_ASSERT failed in qt_win_display_dc()


在Qt中编程调试时有时会发生一个奇怪的错误,在qt_win_display_dc()函数中会发生Assert Failed,导致程序崩溃。该函数的代码如下:

  1. Q_GUI_EXPORT HDC qt_win_display_dc()                  // get display DC   
  2. {  
  3.     Q_ASSERT(qApp && qApp->thread() == QThread::currentThread());  
  4.     if (!displayDC)  
  5.         displayDC = GetDC(0);  
  6.     return displayDC;  
  7. }   

Assert所判断的意思是当前运行的线程不是程序的主线程,也就是Qt中认为这段程序应该在主线程中执行才可以。最后知道是在其他的线程中要调用字体显示方面的函数,才导致这里的异常。

也有人说可以将这句Assert注释掉在编译Qt的源码来解决该问题,但是个人觉得既然源程序中这么写总是有原因的,简单的去掉这个Assert可能会造成其他的未知错误。所以还是从程序结构上来考虑如何避免该操作。

在Qt的文档中有这样的一些说明,摘录如下供参考。

In GUI applications, the main thread is also called the GUI thread because it's the only thread that is allowed to perform GUI-related operations.

Although QObject is reentrant, the GUI classes, notably QWidget and all its subclasses, are not reentrant. They can only be used from the main thread.

As mentioned, each program has one thread when it is started. This thread is called the "main thread" (also known as the "GUI thread" in Qt applications). The Qt GUI must run in this thread. All widgets and several related classes, for example QPixmap, don't work in secondary threads. A secondary thread is commonly referred to as a "worker thread" because it is used to offload processing work from the main thread.

相关内容