PDA

View Full Version : "QPixmap: Must construct a QGuiApplication before a QPixmap" Debug Error!



Miss_Mc
5th August 2019, 15:40
While running our app developed on Windows 10 and closing the gui window with the "X" button we get a Microsoft Visual C++ Runtime Library Error (see attachment).
When running in debug mode an exception is triggered in the QApplication::exec() method.

13218

This is our main function:


int main(int argc, char *argv[])
{
QApplication app(argc, argv);
GeDetektEventFilter filter;
app.installNativeEventFilter(&filter);

std::unique_ptr<Sentinel>& sentinel = Sentinel::getInstance();
sentinel->connectThreads();
sentinel->createAppFiles();
sentinel->startQmlEngine();

sentinel->startHardware();

manager::connections::connectAll();

//Uncomment this to deactivate tests (not recommended)
::testing::InitGoogleTest(&argc, argv);
RUN_ALL_TESTS();

return qApp->exec();
}

Our Gui is created with QtQuick and qml.


import QtQuick 2.2
import QtQuick.Window 2.12
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.12

import DisplayInformation 1.0

Window
{
id: mainWindow

visible: true
width: displayInformation.WINDOW_SIZE.width + displayInformation.SIDE_BAR_WIDTH
height: displayInformation.WINDOW_SIZE.height
title: qsTr("Sentinel")

maximumHeight: height
maximumWidth: width
minimumHeight: height
minimumWidth: width

//Old Qt Bug Displays error here although functional
onClosing:
{
sentinel.stopComClient();
}

Rectangle
{
id: mainArea
Keys.onPressed:
{
if (event.key === Qt.Key_F9)
{
sidebarLoader.source = ""
qmlEngine.clearCache()
sidebarLoader.source = "Sidebar.qml"

imageDisplayLoader.source = ""
qmlEngine.clearCache()
imageDisplayLoader.source = "ImageDisplay.qml"

if (mainArea.logOpen === true)
{
mainArea.logWindow.close()
mainArea.logComponent.source = ""
qmlEngine.clearCache()
mainArea.logComponent.source = "LogWindow.qml"
}

console.log("Sources Reloaded");

event.accepted = true;
}

if (event.key === Qt.Key_L && logOpen === false)
{
sentinel.startHardware()

console.log("Log Window")
logComponent = Qt.createComponent("LogWindow.qml")
logWindow = logComponent.createObject(mainWindow)

logWindow.show()
logOpen = true
}
}

Connections
{
target: mainArea.logWindow
onClosing:
{
console.log("Log Window closed")
mainArea.logOpen = false
}
}

property bool scanAvailable: false
property bool scanStopped: true
property bool logOpen: false
property Window logWindow
property Component logComponent
}

RowLayout
{
id: rowLayout
anchors.fill: parent

Loader
{
id: imageDisplayLoader
source: "ImageDisplay.qml"
}

Loader
{
id: sidebarLoader
Layout.fillHeight: true
Layout.fillWidth: true
source: "Sidebar.qml"
}
}
}


The qml files are loaded in following function over an environment variable:


void Sentinel::startQmlEngine()
{
qmlRegisterType<gui::DisplayInformation>("DisplayInformation", 1, 0, "DisplayInformation");
qmlRegisterType<gui::ImageItem>("ImageItem",1,0,"ImageItem");
qmlRegisterType<gui::ImageProvider>("ImageProvider", 1, 0, "ImageProvider");

m_qmlEngine.rootContext()->setContextProperty("displayInformation",
&m_imageProvider.getDisplayInformation());

m_qmlEngine.rootContext()->setContextProperty("sentinel", this);
m_qmlEngine.rootContext()->setContextProperty("imageProvider", &m_imageProvider);
m_qmlEngine.rootContext()->setContextProperty("scanArea", modules::ScanArea::getInstance().get());
m_qmlEngine.rootContext()->setContextProperty("comClient", modules::ComClient::getInstance().get());
m_qmlEngine.rootContext()->setContextProperty("ptu", modules::PtuControl::getInstance().get());
m_qmlEngine.rootContext()->setContextProperty("logOutput", helpers::LogOutput::getInstance().get());
m_qmlEngine.rootContext()->setContextProperty("qmlEngine", &m_qmlEngine);

m_qmlEngine.load(qEnvironmentVariable("MAIN_QML"));
assert(!m_qmlEngine.rootObjects().isEmpty());

//These are the connections interfacing module state to gui (image processing methods and qml)
using namespace modules;

QObject::connect(&m_imageProvider,
&gui::ImageProvider::backgroundChanged,
this, &Sentinel::updateBackgroundS);

QObject::connect(ComClient::getInstance().get(),
&ComClient::compoundsNameAndStateChanged,
this, &Sentinel::updateCompoundsS);

QObject::connect(GigECamera::getInstance().get(),
&GigECamera::newFrameAvailable,
&m_imageProvider,
&gui::ImageProvider::updateBackgroundImage);

QObject::connect(ToxelBufferExtractor::getInstance ().get(),
&ToxelBufferExtractor::updateToxelPixel,
&m_imageProvider,
&gui::ImageProvider::paintNewOverlayCircle);
}


I've researched for quite a bit to find a solution for this and have seen there were some reported bugs refering to this error. However, I am not sure if and when these bugs have been fixed or even apply to our problem.
There might also be something missing in the way we create and quit the app as this is a very general application scenario for a Qt app and quite a disturbing behaviour.

Very grateful for any suggestions.

anda_skoa
5th August 2019, 16:16
The error usually only happens at startup but you are saying it happens after the application has run successfully and you are closing its window, correct?

Cheers,
_