• 【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
  • 相关阅读:
    2019 ccpc女生赛 Tree
    K8S-存储卷,pv,pvc
    想去银行测试?那这套题目你必须要会
    SQLite事务处理
    面试题库(九):ORM框架 Mybatis,Hibernate和JPA
    HBase 常见问题总结(一)
    VUE模板编译的实现原理
    【机器学习合集】泛化与正则化合集 ->(个人学习记录笔记)
    Selenium定位元素
    ARM体系架构
  • 原文地址:https://blog.csdn.net/MrHHHHHH/article/details/133955877