Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Instantiate QGraphicsScene within QtQuick2 app crashes



  • Hi, I'm adaptating a QtWidgets program interface to QtQuick2. Everything was fine until I reached to call a C++ function to create an A4 page in a QGraphicsScene and then exporting it to PDF. The problem is at instantiating QGraphicsScene in this method member of a class I developed to this purpose, that inherits QtObject. Debugging doesn't give me more information.

    This are the includes in .pro :

    QT       += core gui quick
    QT       += network charts printsupport sql
    QT       += webengine
    

    And this is the piece of code in question:

    bool PDFGenerator::newFile()
    {
        if(printer != nullptr)
            delete printer;
        printer = new QPrinter(QPrinter::ScreenResolution);
    
        if(!name.isEmpty() && !destination.isEmpty()) {
            printer->setOutputFileName(destination + "/debrief_" + name + ".pdf");
        } else {
            return false;
        }
    
        printer->setOutputFormat(QPrinter::PdfFormat);
        printer->setPageSize(QPageSize(QPageSize::A4));
        printer->pageLayout().setMode(QPageLayout::FullPageMode);
    
    
        if(painter != nullptr)
        {
            delete painter;
        }
        painter = new QPainter();
        if(!painter->begin(printer))
        {
            qDebug() << "Error painting";
            return false;
        }
    
    
        if(scene != nullptr)
        {
            scene->deleteLater();
        }
    
        scene = new QGraphicsScene(this);
        scene->setSceneRect(QRect(0.0, 0.0, printer->width(), printer->height()));
    
    
        currentPage = 1;
        cursorYPos = 100;
    
        setTemplate();
    
        return true;
    }
    


  • Never mind, I found the solution.
    It was just changing QGuiApplication to QApplication. I was supposing that QGuiApplication was completly different from QApplication and also necesary for QtQuick2. I didn't knew QApplication was an extension of QtGuiApplication. Now it's working like a charm.
    Thanks you all folks.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Are you sure you initialized all your pointers correctly ?
    Since you are deleting all these object if created earlier, why not make them stack allocated so they live only during the lifetime of that function ?



  • Hi, thank you for your replay.
    I've been testing since I asked and what you are saying was one of the tests, it crashes anyway.
    One of the things I'm finding to be the most probable to be the cause, is that before the change to QtQuick2 I had initialized in main.cpp a QApplication, and now I have a QGuiApplication. I don't know where, but I read that that could be the cause, because in the init of QGraphicsScene it tries to access some member of QApplication.
    So I tried to initiate a QApplication in a thread and there initiate QGraphicsScene, but unfortunately that didn't result because despite being in another thread the debugger reported that only one QApp could be initialized.
    May that be the cause?


  • Lifetime Qt Champion

    @Vitama Did you try what @SGaist suggested?

    bool PDFGenerator::newFile()
    {
        QPrinter printer(QPrinter::ScreenResolution);
    
        if(!name.isEmpty() && !destination.isEmpty()) {
            printer.setOutputFileName(destination + "/debrief_" + name + ".pdf");
        } else {
            return false;
        }
    
        printer.setOutputFormat(QPrinter::PdfFormat);
        printer.setPageSize(QPageSize(QPageSize::A4));
        printer.pageLayout().setMode(QPageLayout::FullPageMode);
    
        QPainter() painter;
        if(!painter.begin(printer))
        {
            qDebug() << "Error painting";
            return false;
        }
    
        scene = new QGraphicsScene(this);
        scene->setSceneRect(QRect(0.0, 0.0, printer.width(), printer.height()));
    
    
        currentPage = 1;
        cursorYPos = 100;
    
        setTemplate();
    
        return true;
    }
    

    But what I don't understand: you create a printer and painter, call begin on painter and then ... you do not do anything?



  • @jsulm Yes, I've tested what @SGaist said. And yes, I do things with them, but on demand. I have other functions, like setTemplate() that do the actual painting job using QGraphicsScene.
    As you can see, I call setTemplate() at the end of the function, but it never reaches that point as it crashes in the instantiation of QGraphicsScene.


  • Moderators

    @Vitama
    I#M surprised it compiled at all, QGraphicsScene requires the widgets module QT += widgets. I assume you did not clean your build directory after removing the module



  • Hi, I think it compiled because core or gui includes widgets, I supose that because to do the change I just added quick to the first line, I didn't removed any module and it was working before, so it must be included as I said.
    And yes I've cleaned the project various times, I've even deleted the whole compilation folder because I upgraded the project from Qt 5.12 to 5.13.1 recently and I wanted it fresh.



  • Never mind, I found the solution.
    It was just changing QGuiApplication to QApplication. I was supposing that QGuiApplication was completly different from QApplication and also necesary for QtQuick2. I didn't knew QApplication was an extension of QtGuiApplication. Now it's working like a charm.
    Thanks you all folks.


  • Lifetime Qt Champion

    Historically, it's the other way around, QGuiApplication came after QApplication and was created for projects not using widgets. However, QApplication inherits from QGuiApplication.


Log in to reply