• 【QPixmap】: Must construct a QGuiApplication before a QPixmap原因及解决方案


    问题复现

    如果运行下面这段代码,会出现什么问题?

    const QPixmap pixmap(":/image/bird.png");
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        ui->pushButton->setIcon(QIcon(pixmap));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    答:会提示异常并退出程序

    QPixmap: Must construct a QGuiApplication before a QPixmap
    // 翻译:
    // QPixmap:必须在QPixmap之前构造一个QGuiApplication对象。
    
    • 1
    • 2
    • 3

    原因

    根据提示,是QPixmap报的错,因此先找QPixmap的官方文档。
    发现一个注意事项:

    Note: When using the native X11 graphics system, the pixmap becomes invalid when the QApplication instance is destroyed.
    // 注意:使用本机X11图形系统时,销毁QApplication实例后,像素图将会无效。
    
    • 1
    • 2

    好像与问题关系不大,就继续找其父类(QPaintDevice)看看能不能找出原因。
    QPaintDevice文档中有以下描述:

    Warning: Qt requires that a QGuiApplication object exists before any paint devices can be created. Paint devices access window system resources, and these resources are not initialized before an application object is created.
    // 警告:在创建任何绘画设备之前,Qt要求先存在QGuiApplication对象。
    // 绘图设备访问窗口系统资源,并且在创建应用程序对象之前是不会初始化这些资源。
    
    • 1
    • 2
    • 3

    继续查看QPixmap源码:

    QPixmap::QPixmap(const QString& fileName,...)
        : QPaintDevice()
    {
        ...
        if (!qt_pixmap_thread_test())
            return;
    
        ...
    }
    
    static bool qt_pixmap_thread_test()
    {
        // 如果QCoreApplication没有实例化,给出异常
        if (Q_UNLIKELY(!QCoreApplication::instance())) {
            // 
            qFatal("QPixmap: Must construct a QGuiApplication before a QPixmap");
            return false;
        }
    
        ...
        return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    根据源码能看出,必须要创建QGuiApplication/QApplication之后才能去实例化QPaintDevice(QPixmap)。

    修改

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        const QPixmap pixmap(":/image/bird.png");
        ui->pushButton->setIcon(QIcon(pixmap));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注意

    只要是QPaintDevice的子类都需遵循以上。
    包括:

    QImage
    QOpenGLPaintDevice
    QPagedPaintDevice
    QPaintDeviceWindow
    QPicture
    QPixmap
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如果是Qt的其他类内有用到QPaintDevice或其子类时也需遵循以上。

    QIcon()
    
    • 1
  • 相关阅读:
    爱粤语软件:普通话和粤语转换
    基于 jetpack compose,使用MVI架构+自定义布局实现的康威生命游戏
    从零开始, 开发一个 Web Office 套件 (3): 鼠标事件
    华为od德科面试数据算法解析 2022-8-8 欢乐的周末
    总在用户态调试 C# 程序,终还是搭了一个内核态环境
    React hooks之useCallback的使用场景及其深度解读
    CY8C5888AXQ-LP096 CY8C5888AXI-LP096,IC MCU 32BIT
    HashMap和HashTable的区别
    行为设计模式之状态模式
    【毕业设计】基于深度学习卷积神经网络的手势识别算法 - python opencv 机器视觉
  • 原文地址:https://blog.csdn.net/MrHHHHHH/article/details/133955877