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.
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.