antonypro / QGoodWindow

QGoodWindow - border less window for Qt 5 and Qt 6
MIT License
516 stars 92 forks source link

QQuickWidget causes program crash when closing QGoodWindow #36

Closed galvinhoang closed 1 year ago

galvinhoang commented 1 year ago

I am using your example ExampleMinimalWindow as a base.

The issue is reproducable by using this as mainwindow.cpp:

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent) : QGoodWindow(parent) {
    m_good_central_widget = new QGoodCentralWidget(this);

    //Contents of the window
    QQuickWidget *bg = new QQuickWidget(this);
    bg->setObjectName("backgroundWidget");

    //Function that sets the state holder theme
    auto func_theme = [=] {
        qGoodStateHolder->setCurrentThemeDark(QGoodWindow::isSystemThemeDark());
    };

    //React to state holder theme change and apply our dark or light theme to the whole app
    connect(qGoodStateHolder, &QGoodStateHolder::currentThemeChanged, this, [=] {
                if (qGoodStateHolder->isCurrentThemeDark())
                setAppDarkTheme();
                else {
                        setAppLightTheme();
                    }
                });

    //React to system theme change
    connect(this, &QGoodWindow::systemThemeChanged, this, func_theme);

    //Set the central widget of QGoodCentralWidget
    m_good_central_widget->setCentralWidget(bg);

    //Set the central widget of QGoodWindow which is QGoodCentralWidget
    setCentralWidget(m_good_central_widget);

    //Set initial theme
    func_theme();
}

MainWindow::~MainWindow() {
    qDebug() << "Destructor is executed after the warning";
}

When closing the window, I get the following warning just before the program crashes:

QRhi 0x1f60bef8030 going down with 3 unreleased resources that own native graphics objects. This is not nice.
  RenderBuffer resource 0x1f60a2339d0 ()
  Texture resource 0x1f60bea3f10 ()
  TextureRenderTarget resource 0x1f60c11dd60 ()
Destructor is executed after the warning
- TIME - : - MY PROJECT PATH\example.exe crashed.

So this is not catastrophic and I'll continue using the QQuickWidget because otherwise the program always works out fine. The average user may not care if the program crashes instead of closing properly (if he wanted the program to end anyway), but I thought, I report it as I didn't manage to really fix it and maybe you know what this is about.

When asking ChatGPT, it suggested to execute bg->deleteLater(); when trying to close the program, however, the warning was always thrown before an implementation of bg->deleteLater() (for example in a closeEvent override) was executed in the code.

Qt source code (https://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/rhi/qrhi.cpp at line 7506) indicates, that the application somehow manages to destroy the resources of a QRhi after the QRhi itself. (but didn't figure out yet, what exactly that means, I'll let you know if I find out anything interesting about it).

antonypro commented 1 year ago

@galvinhoang: Hi!

I'm also have seen this problem in my tests, the solution (that i found), is prevent the application from exit before the widget gets destroyed.

Something like this:

Hold a QPointer of the widget:

QPointer<QQuickWidget> m_quick_widget;

And delete that widget if it remains valid in close event:

void MainWindow::closeEvent(QCloseEvent *event)
{
    if (m_quick_widget)
    {
        QEventLoop loop;
        connect(m_quick_widget, &QQuickWidget::destroyed, &loop, &QEventLoop::quit);
        QTimer::singleShot(0, m_quick_widget, &QQuickWidget::deleteLater);
        loop.exec();
    }
}

This will be present in the next version to be published this week (If everything is good).

galvinhoang commented 1 year ago

Ah great to know! Thanks so much for the info!

antonypro commented 1 year ago

@galvinhoang: This bug was solved on version 2.4. Note that the closeEvent delete workaround is no more needed.