QGuiApplicationPrivate

QGuiApplicationPrivate

使用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调用上的段故障,给出以下堆栈跟踪,以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并没有什么不同。

最佳答案

查看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绘制文本。

09-27 15:59