Ribasim icon indicating copy to clipboard operation
Ribasim copied to clipboard

ribasim_qgis crashes QGIS 3.34+

Open visr opened this issue 1 year ago • 5 comments

QGIS LTS 3.28 works, but 3.34.4 and 3.36.0 crash when I try to start the plugin. This doesn't seems to happen all the time, though most times it does.

Python Stack Trace
Windows fatal exception: access violation

Current thread 0x00005b4c (most recent call first):
  File "C:\Users/visser_mn/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\ribasim_qgis\widgets\ribasim_widget.py", line 47 in __init__
    self.tabwidget.addTab(self.__dataset_widget, "Model")
  File "C:\Users/visser_mn/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\ribasim_qgis\ribasim_qgis.py", line 48 in toggle_ribasim
    widget = RibasimWidget(self.ribasim_widget, self.iface)


Stack Trace


QHeaderView::resizeSections :
QHeaderView::sectionSize :
QTreeViewPrivate::updateScrollBars :
QTreeView::updateGeometries :
PyInit_QtWidgets :
QObject::qt_static_metacall :
QHeaderView::viewportEvent :
QCoreApplicationPrivate::sendThroughObjectEventFilters :
QApplicationPrivate::notify_helper :
QApplication::notify :
QgsApplication::notify :
QCoreApplication::notifyInternal2 :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidget::setParent :
QWidgetPrivate::setWidgetParentHelper :
QLayout::addChildWidget :
QStackedLayout::insertWidget :
QTabWidget::addTab :
PyInit_QtWidgets :
PyObject_Str :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyFunction_Vectorcall :
PyArg_ParseTuple_SizeT :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyObject_GC_Del :
PyVectorcall_Call :
PyObject_Call :
PyInit_QtCore :
PyInit_QtCore :
PyInit_QtCore :
PyInit_QtCore :
QObject::qt_static_metacall :
QAction::activate :
QAbstractButton::click :
QAbstractButton::mouseReleaseEvent :
QToolButton::mouseReleaseEvent :
QWidget::event :
QApplicationPrivate::notify_helper :
QApplication::notify :
QgsApplication::notify :
QCoreApplication::notifyInternal2 :
QApplicationPrivate::sendMouseEvent :
QSizePolicy::QSizePolicy :
QSizePolicy::QSizePolicy :
QApplicationPrivate::notify_helper :
QApplication::notify :
QgsApplication::notify :
QCoreApplication::notifyInternal2 :
QGuiApplicationPrivate::processMouseEvent :
QWindowSystemInterface::sendWindowSystemEvents :
QEventDispatcherWin32::processEvents :
qt_plugin_query_metadata :
QEventLoop::exec :
QCoreApplication::exec :
main :
BaseThreadInitThunk :
RtlUserThreadStart :




QGIS Info
QGIS Version: 3.34.3-Prizren
QGIS code revision: 47373234ac
Compiled against Qt: 5.15.3
Running against Qt: 5.15.3
Compiled against GDAL: 3.8.3
Running against GDAL: 3.8.3



System Info
CPU Type: x86_64
Kernel Type: winnt
Kernel Version: 10.0.19045

visr avatar Jan 26 '24 12:01 visr

Turns out I somehow deleted all folders in the ribasim_qgis folder.

visr avatar Jan 26 '24 12:01 visr

I just saw the same thing on first startup of the Ribasim plugin on a clean install. Trying a second time it works. @Huite also sees this sometimes.

Jingru923 avatar Feb 13 '24 10:02 Jingru923

QGIS currently uses Qt 5, but is in the progress of upgrading to Qt 6. Would be interesting to see if we can get our hands on a Qt 6 build to see if that fixes this. Though general availability of this will take a while so we should still look into actually fixing this.

visr avatar Mar 18 '24 10:03 visr

QGIS on macOS seems to work fine (for now). Am on 3.36.

evetion avatar May 16 '24 11:05 evetion

Haven't seen this recently, now on 3.36.3. And sometimes using LTR 3.34.7. Post here if you see the issue on this or later releases.

visr avatar May 23 '24 11:05 visr

Nevermind, just saw this again on 3.36.3.

visr avatar May 27 '24 11:05 visr

I've been seeing these crashes off and on again (also in the brother and sisters plugins). Sometimes, it's the plugin reloader forcing a reload which causes QGIS to crash. I'm wondering whether it's due to the reference to iface being stored in the widget. It specifically complains about some access violation in the crash report, mentioning the line where the widget is initialized.

The iface object is barely used in the plugin, and it can be fetched if needed. Might be worth adjusting a few lines to see if this helps against the crashes.

EDIT: taking a look at this, not sure the iface can actually be fetched that easily...

Huite avatar Jun 20 '24 16:06 Huite

Looking at some other popular plugins, storing iface seems common practice. Our problem, and I assume the imod qgis one as well, lies slightly deeper in some widget link/state? I also saw we don't unload everything we load, but that wouldn't explain crashes on starting.

Might be linked to the horrible non-deterministic failings of our QGIS CI?

evetion avatar Jun 21 '24 05:06 evetion

I think I might have been a bit too hasty at pointing at iface. In one of the other plugins, relatively many crashes seemed to originate from a line setting the column width of the DatasetTreeWidget, with self.setColumnWidth(0, 1). This happens at initialization / reloading. I've removed the line there, and it seems a little more stable, but that's really just a feeling.

I've based the Ribasim plugin off of the qgis-tim one: https://github.com/deltares/qgis-tim The imod-qgis plugin also stores references everywhere: https://github.com/Deltares/imod-qgis

Across these plugins, the reason an iface reference is kept around is for:

  • Access to the message bar
  • Access to the Map Canvas
  • Connecting to the signals for when a QGIS project is read or newly created.

My feeling is that the imod-qgis plugin seems to crash a lot less. I've also been getting crashes on innocuous seeming stuff, like creating a vector layer via PyQGIS.

I still don't have a lot of concrete ideas. I suggest we starting logging the crashes here, and including the stacktraces in a spoiler section.

Huite avatar Jun 21 '24 08:06 Huite

Okay to trigger it was pretty easy: start QGIS, click Ribasim button, click plugin reloader to reload Ribasim plugin, click Ribasim button, crash.

It crashed here on: self.tabwidget.addTab(self.__dataset_widget, "Model")

In the Qt stack trace, it's somewhat interesting that QHeaderView::resizeSections is mentioned, which I think is also involved with the self.setColumnWidth(0, 1) above. But I'm still grasping at straws.


Python Stack Trace
Windows fatal exception: access violation

Current thread 0x000031d4 (most recent call first):
  File "C:\Users/bootsma/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\ribasim_qgis\widgets\ribasim_widget.py", line 47 in __init__
    self.tabwidget.addTab(self.__dataset_widget, "Model")
  File "C:\Users/bootsma/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\ribasim_qgis\ribasim_qgis.py", line 48 in toggle_ribasim
    widget = RibasimWidget(self.ribasim_widget, self.iface)


Stack Trace


QHeaderView::resizeSections :
QHeaderView::sectionSize :
QTreeViewPrivate::updateScrollBars :
QTreeView::updateGeometries :
PyInit_QtWidgets :
QObject::qt_static_metacall :
QHeaderView::viewportEvent :
QCoreApplicationPrivate::sendThroughObjectEventFilters :
QApplicationPrivate::notify_helper :
QApplication::notify :
QgsApplication::notify :
QCoreApplication::notifyInternal2 :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidget::setParent :
QWidgetPrivate::setWidgetParentHelper :
QLayout::addChildWidget :
QStackedLayout::insertWidget :
QTabWidget::addTab :
PyInit_QtWidgets :
PyLong_FromString :
PyObject_Vectorcall :
PyObject_Vectorcall :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyNumber_Long :
PyObject_Vectorcall :
PyObject_Vectorcall :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyArg_CheckPositional :
PyObject_Call :
PyObject_Call :
PyInit_QtCore :
PyInit_QtCore :
PyInit_QtCore :
PyInit_QtCore :
QObject::qt_static_metacall :
QAction::activate :
QAbstractButton::click :
QAbstractButton::mouseReleaseEvent :
QToolButton::mouseReleaseEvent :
QWidget::event :
QApplicationPrivate::notify_helper :
QApplication::notify :
QgsApplication::notify :
QCoreApplication::notifyInternal2 :
QApplicationPrivate::sendMouseEvent :
QSizePolicy::QSizePolicy :
QSizePolicy::QSizePolicy :
QApplicationPrivate::notify_helper :
QApplication::notify :
QgsApplication::notify :
QCoreApplication::notifyInternal2 :
QGuiApplicationPrivate::processMouseEvent :
QWindowSystemInterface::sendWindowSystemEvents :
QEventDispatcherWin32::processEvents :
qt_plugin_query_metadata :
QEventLoop::exec :
QCoreApplication::exec :
main :
BaseThreadInitThunk :
RtlUserThreadStart :




QGIS Info
QGIS Version: 3.34.7-Prizren
QGIS code revision: 6f7d735c
Compiled against Qt: 5.15.13
Running against Qt: 5.15.13
Compiled against GDAL: 3.9.0
Running against GDAL: 3.9.0



System Info
CPU Type: x86_64
Kernel Type: winnt
Kernel Version: 10.0.19045

Huite avatar Jun 21 '24 08:06 Huite

Can you try to do the same for the imod plugin? The stacktrace was lacking in the related issue.

I've also seen some (example) plugins having a first run variable, to only initialize GUI elements once, and not on reload? Might be worth investigating. I would love to help some more, but I can't reproduce the crash on my mac (not sure what that says about the bug).

evetion avatar Jun 21 '24 08:06 evetion

Here's a crash generated from reloading and starting the timeseries widget repeatedly:

Python Stack Trace
Windows fatal exception: access violation

Current thread 0x00003818 (most recent call first):
  File "C:\PROGRA~1/QGIS33~1.7/apps/qgis-ltr/./python\qgis\core\additions\qgsfunction.py", line 143 in register_function
    if register and QgsExpression.isFunctionName(name):
  File "C:\PROGRA~1/QGIS33~1.7/apps/qgis-ltr/./python\qgis\core\additions\qgsfunction.py", line 286 in wrapper
    return register_function(func, args, group, **kwargs)
  File "C:\Users/bootsma/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\imodqgis\ipf\ipf_dialog.py", line 30 in 
    @qgsfunction(args="auto", group="Custom", usesGeometry=False)
  File "C:\PROGRA~1/QGIS33~1.7/apps/qgis-ltr/./python\qgis\utils.py", line 892 in _import
    mod = _builtin_import(name, globals, locals, fromlist, level)
  File "C:\Users/bootsma/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\imodqgis\ipf\__init__.py", line 4 in 
    from imodqgis.ipf.ipf_dialog import ImodIpfDialog
  File "C:\PROGRA~1/QGIS33~1.7/apps/qgis-ltr/./python\qgis\utils.py", line 892 in _import
    mod = _builtin_import(name, globals, locals, fromlist, level)
  File "C:\Users/bootsma/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\imodqgis\timeseries\timeseries_widget.py", line 44 in 
    from imodqgis.ipf import IpfType, read_associated_timeseries
  File "C:\PROGRA~1/QGIS33~1.7/apps/qgis-ltr/./python\qgis\utils.py", line 892 in _import
    mod = _builtin_import(name, globals, locals, fromlist, level)
  File "C:\Users/bootsma/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\imodqgis\timeseries\__init__.py", line 4 in 
    from imodqgis.timeseries.timeseries_widget import ImodTimeSeriesWidget
  File "C:\PROGRA~1/QGIS33~1.7/apps/qgis-ltr/./python\qgis\utils.py", line 892 in _import
    mod = _builtin_import(name, globals, locals, fromlist, level)
  File "C:\Users/bootsma/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\imodqgis\imod_plugin.py", line 127 in toggle_timeseries
    from imodqgis.timeseries import ImodTimeSeriesWidget


Stack Trace


QBitArray::QBitArray :
QgsExpression::functionIndex :
QgsExpression::isFunctionName :
pdal::MetadataNode::value :
PyLong_FromString :
PyObject_Vectorcall :
PyObject_Vectorcall :
PyEval_EvalFrameDefault :
PyType_CalculateMetaclass :
PyEval_EvalCode :
PyObject_CallMethodObjArgs :
PyObject_CallMethodObjArgs :
PyUnicode_RichCompare :
PyObject_Call :
PyObject_Call :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyObject_Vectorcall :
PyObject_CallMethodObjArgs :
PyObject_CallMethodObjArgs :
PyConfig_FromDict :
PyImport_ImportModuleLevelObject :
PySet_Add :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyObject_Vectorcall :
PyObject_FastCall :
PyThread_tss_is_created :
PyEval_EvalFrameDefault :
PyType_CalculateMetaclass :
PyEval_EvalCode :
PyObject_CallMethodObjArgs :
PyObject_CallMethodObjArgs :
PyUnicode_RichCompare :
PyObject_Call :
PyObject_Call :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyObject_Vectorcall :
PyObject_CallMethodObjArgs :
PyObject_CallMethodObjArgs :
PyConfig_FromDict :
PyImport_ImportModuleLevelObject :
PySet_Add :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyObject_Vectorcall :
PyObject_FastCall :
PyThread_tss_is_created :
PyEval_EvalFrameDefault :
PyType_CalculateMetaclass :
PyEval_EvalCode :
PyObject_CallMethodObjArgs :
PyObject_CallMethodObjArgs :
PyUnicode_RichCompare :
PyObject_Call :
PyObject_Call :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyObject_Vectorcall :
PyObject_CallMethodObjArgs :
PyObject_CallMethodObjArgs :
PyConfig_FromDict :
PyImport_ImportModuleLevelObject :
PySet_Add :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyObject_Vectorcall :
PyObject_FastCall :
PyThread_tss_is_created :
PyEval_EvalFrameDefault :
PyType_CalculateMetaclass :
PyEval_EvalCode :
PyObject_CallMethodObjArgs :
PyObject_CallMethodObjArgs :
PyUnicode_RichCompare :
PyObject_Call :
PyObject_Call :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyObject_Vectorcall :
PyObject_CallMethodObjArgs :
PyObject_CallMethodObjArgs :
PyConfig_FromDict :
PyImport_ImportModuleLevelObject :
PySet_Add :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyObject_Vectorcall :
PyObject_FastCall :
PyThread_tss_is_created :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyArg_CheckPositional :
PyObject_Call :
PyObject_Call :
PyInit_QtCore :
PyInit_QtCore :
PyInit_QtCore :
PyInit_QtCore :
QObject::qt_static_metacall :
QAction::activate :
QAbstractButton::click :
QAbstractButton::mouseReleaseEvent :
QToolButton::mouseReleaseEvent :
QWidget::event :
QApplicationPrivate::notify_helper :
QApplication::notify :
QgsApplication::notify :
QCoreApplication::notifyInternal2 :
QApplicationPrivate::sendMouseEvent :
QSizePolicy::QSizePolicy :
QSizePolicy::QSizePolicy :
QApplicationPrivate::notify_helper :
QApplication::notify :
QgsApplication::notify :
QCoreApplication::notifyInternal2 :
QGuiApplicationPrivate::processMouseEvent :
QWindowSystemInterface::sendWindowSystemEvents :
QEventDispatcherWin32::processEvents :
qt_plugin_query_metadata :
QEventLoop::exec :
QCoreApplication::exec :
main :
BaseThreadInitThunk :
RtlUserThreadStart :

One thing to note is that there's double memory management going with these pyqt bindings, the Python interpreter and Qt both allocate and free memory. Sometimes I wonder whether there's some maybe some lag between them. These access violations make me thing the Python things try to access something that isn't there yet or something.

I don't think we're doing anything fishy by the way, I think this is a memory bug or something in QGIS or Qt. Ideally we can find a way to circumvent it.

Huite avatar Jun 21 '24 10:06 Huite

Indeed, but if we can circumvent it, we can report it (QGIS issue tracker is rife with memory crashes without details). Ideally you would debug the Python plugin , so you can find some specifics.

Other interesting debugging tools are https://github.com/wonder-sk/qgis-first-aid-plugin, or https://gist.github.com/thbaumann/73c873d4c49d8c1add8dc97359cebabe.

evetion avatar Jun 21 '24 11:06 evetion

Unfortunately, I don't think debugging Python will do much good. We are not getting a Python exception -- I don't think we're even crashing the Python interpreter. And even if were to inspect the Python objects during debugging, you would find nothing amiss. You would have to debug the QGIS C++ application instead, right?

Regardless, I'll try and keep on posting stack traces. Hopefully we can find something of a pattern.

Huite avatar Jun 21 '24 12:06 Huite

Just updated to QGIS 3.38 RC, got it on first load of the Ribasim plugin. Stacktrace below.

You would have to debug the QGIS C++ application instead, right?

I guess, https://github.com/qgis/QGIS/blob/master/INSTALL.md#4-building-on-windows, but that doesn't seem very straightforward, since they just point to https://github.com/jef-n/OSGeo4W/blob/master/src/qgis-dev/osgeo4w/package.sh for the actual build steps.

Copy Report

Report Details

Python Stack Trace

Windows fatal exception: access violation

Current thread 0x00006b18 (most recent call first):
  File "C:\Users/visser_mn/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\ribasim_qgis\widgets\ribasim_widget.py", line 47 in __init__
    self.tabwidget.addTab(self.__dataset_widget, "Model")
  File "C:\Users/visser_mn/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\ribasim_qgis\ribasim_qgis.py", line 48 in toggle_ribasim
    widget = RibasimWidget(self.ribasim_widget, self.iface)

Stack Trace


QHeaderView::resizeSections :
QHeaderView::sectionSize :
QTreeViewPrivate::updateScrollBars :
QTreeView::updateGeometries :
PyInit_QtWidgets :
QObject::qt_static_metacall :
QHeaderView::viewportEvent :
QCoreApplicationPrivate::sendThroughObjectEventFilters :
QApplicationPrivate::notify_helper :
QApplication::notify :
QgsApplication::notify :
QCoreApplication::notifyInternal2 :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidget::setParent :
QWidgetPrivate::setWidgetParentHelper :
QLayout::addChildWidget :
QStackedLayout::insertWidget :
QTabWidget::addTab :
PyInit_QtWidgets :
PyObject_Call :
PyObject_Vectorcall :
PyObject_Vectorcall :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyObject_Call_Prepend :
PyObject_Vectorcall :
PyObject_Vectorcall :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
Py_hashtable_compare_direct :
PyObject_Call :
PyObject_Call :
PyInit_QtCore :
PyInit_QtCore :
PyInit_QtCore :
PyInit_QtCore :
QObject::qt_static_metacall :
QAction::activate :
QAbstractButton::click :
QAbstractButton::mouseReleaseEvent :
QToolButton::mouseReleaseEvent :
QWidget::event :
QApplicationPrivate::notify_helper :
QApplication::notify :
QgsApplication::notify :
QCoreApplication::notifyInternal2 :
QApplicationPrivate::sendMouseEvent :
QSizePolicy::QSizePolicy :
QSizePolicy::QSizePolicy :
QApplicationPrivate::notify_helper :
QApplication::notify :
QgsApplication::notify :
QCoreApplication::notifyInternal2 :
QGuiApplicationPrivate::processMouseEvent :
QWindowSystemInterface::sendWindowSystemEvents :
QEventDispatcherWin32::processEvents :
qt_plugin_query_metadata :
QEventLoop::exec :
QCoreApplication::exec :
main :
BaseThreadInitThunk :
RtlUserThreadStart :

QGIS Info QGIS Version: 3.38.0-Grenoble QGIS code revision: 37aa6188bc Compiled against Qt: 5.15.13 Running against Qt: 5.15.13 Compiled against GDAL: 3.9.0 Running against GDAL: 3.9.0

System Info CPU Type: x86_64 Kernel Type: winnt Kernel Version: 10.0.19045

visr avatar Jun 24 '24 09:06 visr

You should install a nightly dev build as

Nightlies are debug builds (including debugging output)

evetion avatar Jun 24 '24 12:06 evetion

Ah, excellent suggestion!

Huite avatar Jun 24 '24 13:06 Huite

In OSGeo4W description for qgis-dev it doesn't mention it is a debug build, but there are also separate qgis-*-pdb for builds with debugging symbols.

visr avatar Jun 24 '24 13:06 visr

Here is a stacktrace on qgis-dev with qgis-dev-pdb, giving a few line numbers:

Details

Report Details

Python Stack Trace

Windows fatal exception: access violation

Current thread 0x0000548c (most recent call first):
  File "C:\Users/visser_mn/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\ribasim_qgis\widgets\ribasim_widget.py", line 47 in __init__
    self.tabwidget.addTab(self.__dataset_widget, "Model")
  File "C:\Users/visser_mn/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\ribasim_qgis\ribasim_qgis.py", line 48 in toggle_ribasim
    widget = RibasimWidget(self.ribasim_widget, self.iface)

Stack Trace


QHeaderView::resizeSections :
QHeaderView::sectionSize :
QTreeViewPrivate::updateScrollBars :
QTreeView::updateGeometries :
PyInit_QtWidgets :
QObject::qt_static_metacall :
QHeaderView::viewportEvent :
QCoreApplicationPrivate::sendThroughObjectEventFilters :
QApplicationPrivate::notify_helper :
QApplication::notify :
QgsApplication::notify qgsapplication.cpp:607
QCoreApplication::notifyInternal2 :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidgetPrivate::setStyle_helper :
QWidgetPrivate::inheritStyle :
QWidget::setParent :
QWidgetPrivate::setWidgetParentHelper :
QLayout::addChildWidget :
QStackedLayout::insertWidget :
QTabWidget::addTab :
PyInit_QtWidgets :
PyObject_Call :
PyObject_Vectorcall :
PyObject_Vectorcall :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyObject_Call_Prepend :
PyObject_Vectorcall :
PyObject_Vectorcall :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
Py_hashtable_compare_direct :
PyObject_Call :
PyObject_Call :
PyInit_QtCore :
PyInit_QtCore :
PyInit_QtCore :
PyInit_QtCore :
QObject::qt_static_metacall :
QAction::activate :
QAbstractButton::click :
QAbstractButton::mouseReleaseEvent :
QToolButton::mouseReleaseEvent :
QWidget::event :
QApplicationPrivate::notify_helper :
QApplication::notify :
QgsApplication::notify qgsapplication.cpp:607
QCoreApplication::notifyInternal2 :
QApplicationPrivate::sendMouseEvent :
QSizePolicy::QSizePolicy :
QSizePolicy::QSizePolicy :
QApplicationPrivate::notify_helper :
QApplication::notify :
QgsApplication::notify qgsapplication.cpp:607
QCoreApplication::notifyInternal2 :
QGuiApplicationPrivate::processMouseEvent :
QWindowSystemInterface::sendWindowSystemEvents :
QEventDispatcherWin32::processEvents :
qt_plugin_query_metadata :
QEventLoop::exec :
QCoreApplication::exec :
main main.cpp:1845
WinMain mainwin.cpp:214
__scrt_common_main_seh exe_common.inl:288
BaseThreadInitThunk :
RtlUserThreadStart :

QGIS Info QGIS Version: 3.37.0-Master QGIS code revision: 684a802617 Compiled against Qt: 5.15.13 Running against Qt: 5.15.13 Compiled against GDAL: 3.10.0dev-5481008668 Running against GDAL: 3.10.0dev-5d4c2d3a3a

System Info CPU Type: x86_64 Kernel Type: winnt Kernel Version: 10.0.19045

I know have 4 versions installed:

  • qgis
  • qgis-dev
  • qgis-ltr
  • qgis-qt6-dev

The Ribasim plugin of course doesn't work on the Qt6 version, listed as invalid, but that's unrelated.

image

It may help to also get debug builds or symbols of Qt5:

5.13.3:
qt5-libs-debug
qt5-libs-debug-symbols

5.15.13:
qt5-libs
qt5-libs-symbols

visr avatar Jun 24 '24 13:06 visr

So it seems it crashes after/on the init (PyInit_QtWidgets) of the DatasetTreeWidget in ribasim. On init, it will active a redraw of the child widget(s), calling updateGeometries, which in turn passes the new size to updatescrollbars, which in turn tries to get/set the size of the column headers (AFAIK). So I would advise to play with https://github.com/Deltares/Ribasim/blob/b425aa1e0e85ebf2981d14521579997b3dfd2ce5/ribasim_qgis/widgets/dataset_widget.py#L47-L56.

edit: We might even get away with setting https://doc.qt.io/qt-5/qwidget.html#updatesEnabled-prop on a higher level?

evetion avatar Jun 24 '24 14:06 evetion

With the help of @evetion I narrowed it down to this line in our code, by repeatedly running pixi run test-ribasim-qgis-ui:

https://github.com/Deltares/Ribasim/blob/b425aa1e0e85ebf2981d14521579997b3dfd2ce5/ribasim_qgis/widgets/dataset_widget.py#L54

@Huite what does this do exactly? I don't see the difference when commenting out that line. In these Qt docs it mentions The logical index should exist at the time this function is called.. Can that be the issue? Or can we call this without the logical index as well?

visr avatar Jun 24 '24 14:06 visr

And as this is C++, shouldn't it be header.setSectionResizeMode(0, QHeaderView.Stretch)? Would be fun if this all comes down to an off by one.

evetion avatar Jun 24 '24 17:06 evetion

In the original plugin, the dataset view has multiple columns (a checkbox, the steady-state input, another checkbox, transient input). These aren't relevant to Ribasim, so it can most likely be removed indeed.

Huite avatar Jun 24 '24 19:06 Huite

In a hobby project (another sibiling for the qgis-tim plugin...), I've removed these lines as well. I've had far, far less crashes: https://github.com/Huite/gflow-plugin/commit/a429dc2b35e7cb7510ff171c5d9bb25f66ad46a4

I should probably adjust the original code in qgis-tim as well: https://github.com/Deltares/QGIS-Tim/blob/2d61c099e8c73e7bcd18e7190a2393d182049a6c/plugin/qgistim/widgets/dataset_widget.py#L76

Since the ColumnCount should probably be set first. (In my defense, the sizing behavior often isn't that predictable and some of this is a result of trial-and-error...)

Huite avatar Jun 24 '24 19:06 Huite