初始化数据库中的 QPainter#drawText 段错误

Posted

技术标签:

【中文标题】初始化数据库中的 QPainter#drawText 段错误【英文标题】:QPainter#drawText seg faults in initializeDb 【发布时间】:2016-10-28 21:33:31 【问题描述】:

使用 Qt 5.7,Windows 7,MinGW 32 位,以下程序:

#include <QImage>
#include <QPainter>

int main () 
    QImage i(100, 100, QImage::Format_RGB888);
    QPainter p(&i);
    p.drawText(0, 0, "abc"); // line 7

p.drawText 调用的 Seg 错误,给出以下堆栈跟踪,以 initializeDb 结尾:

1  initializeDb                  qfontdatabase.cpp 896  0x7930ed0 
2  QFontDatabase::findFont       qfontdatabase.cpp 2640 0x79361f6 
3  QFontDatabase::load           qfontdatabase.cpp 2795 0x7936b5e 
4  QFontPrivate::engineForScript qfont.cpp         215  0x79194ff 
5  QTextEngine::fontEngine       qtextengine.cpp   2094 0x793d24b 
6  QTextEngine::shapeText        qtextengine.cpp   1000 0x7938c0b 
7  QTextEngine::shape            qtextengine.cpp   1534 0x793b090 
8  QTextEngine::shapeLine        qtextengine.cpp   938  0x793884a 
9  QPainter::drawText            qpainter.cpp      5877 0x7a3dc91 
10 QPainter::drawText            qpainter.cpp      5700 0x7a3cfe6 
11 QPainter::drawText            qpainter.h        890  0x402a1e  
12 main                          main.cpp          7    0x4016b6  

为什么会发生这种情况,我怎样才能让它不发生?

.pro 文件,为了完整性:

QT += core gui    
CONFIG += c++11
TARGET = untitled18
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app    
SOURCES += main.cpp

这是用于生成图像的命令行实用程序。

注意:添加QCoreApplication 并没有什么不同。

【问题讨论】:

试试 QApplication 而不是 QCoreApplication。 【参考方案1】:

查看 Qt 源代码可以帮助解决此类问题。

qfontdatabase.cpp 的第 896 行(您的堆栈跟踪显示崩溃发生的位置)如下所示:

QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();   

....所以很可能 platformIntegration() 或 fontDatabase() 出于某种原因返回 NULL。

查看源码我们看到QGuiApplicationPrivate::platformIntegration()定义在这里,在gui/kernel/qguiapplication.h的第103行:

static QPlatformIntegration *platformIntegration()
 return platform_integration; 

...因此,如果尚未将 platform_integration 变量设置为指向任何有效对象,该方法肯定会返回 NULL。

稍微摸索了一下,我们发现设置 platform_integration 静态变量的唯一位置是 gui/kernel/qguiapplication.cpp 的第 1094 行:

QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, argc, argv, platformPluginPath);

...它是名为 init_platform() 的静态函数的一部分,它是从 QGuiApplicationPrivate::createPlatformIntegration() 调用的,它本身是从 QGuiApplicationPrivate 类的各种方法调用的。

当然,除非/直到创建 QGuiApplicationPrivate 对象,否则不能调用任何 QGuiApplicationPrivate 方法,除非/直到您创建了 QGuiApplication 对象,否则这可能不会发生。

所以总结一下...看起来 Rinold 是正确的,您需要先实例化一个 QGuiApplication(或 QApplication,它是 QGuiApplication 的子类)对象,然后再尝试使用 QPainter 绘制文本。

【讨论】:

以上是关于初始化数据库中的 QPainter#drawText 段错误的主要内容,如果未能解决你的问题,请参考以下文章

Qt 5.10 中的 QPainter::drawImage() 故障

用于渲染 2D 文本的 paintGL() 中的着色器和 QPainter 之间的冲突

QPainter 仅在 QImage 上绘制矩形的一部分

paintEvent中的Qt QPainter消除了用paintGL绘制的图形

使用 QPainter 和 paintEvent 在 PYQT5 中的 QLabel 中包含的 Pixmap 上绘制圆圈

QPainter 在使用 QPropertyAnimation 时崩溃