HorizontalHeaderView & VerticalHeaderView does not disconnect from QQmlTableModel::headerDataChanged in Loader
-
Hi
I have table view loaded dynamically. If it is without HorizontalHeaderView and VerticalHeaderView it works fine.
But if I use them in my real application it crash after same time. (but can not reproduce the crash in test app)
Investigation shows that connections from HorizontalHeaderView and VerticalHeaderView still are in model after the unload table view.
If you press many times the button "Reload" in test app you will see in output the model gets more and more connections.Any ideas how to fix it?
Qt 6.4.0
main.qml
import QtQuick import QtQuick.Controls import Qt.labs.qmlmodels import Helper Window { id: window width: 640 height: 480 visible: true title: qsTr("Hello World") Helper { id: helper } Button { id: btnReload text: "Reload" anchors.left: loader.right onClicked: { loader.active = false loader.active = true helper.dumpObjectInfo(tableModel) } } TableModel { id: tableModel TableModelColumn { display: "name" } TableModelColumn { display: "color" } rows: [{ "name": "cat", "color": "black" }, { "name": "dog", "color": "brown" }, { "name": "bird", "color": "white" }] } Loader { id: loader width: 100 height: 300 sourceComponent: comp active: true } Component { id: comp Item { anchors.fill: paren HorizontalHeaderView { id: horizontalHeader implicitHeight: 20 syncView: tableView anchors.left: tableView.left delegate: Rectangle { implicitHeight: 20 implicitWidth: 50 border.width: 1 Text { text: "name" anchors.fill: parent horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter textFormat: Text.PlainText } } } TableView { id: tableView anchors.left: parent.left anchors.right: parent.right anchors.top: horizontalHeader.bottom anchors.bottom: parent.bottom columnSpacing: 1 rowSpacing: 1 clip: true model: tableModel delegate: Rectangle { implicitWidth: 100 implicitHeight: 50 border.width: 1 Text { text: display anchors.centerIn: parent } } } } } }
manu.cpp
#include <QGuiApplication> #include <QQmlApplicationEngine> #include "Helper.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; const QUrl url(u"qrc:/untitled2/main.qml"_qs); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); qmlRegisterType<Helper>("Helper", 1, 0, "Helper"); engine.load(url); return app.exec(); }
Helper.h
#ifndef HELPER_H #define HELPER_H #include <QObject> class Helper: public QObject { Q_OBJECT public: Helper(); Q_INVOKABLE void dumpObjectInfo(QObject* obj); }; #endif // HELPER_H
Helper.cpp
#include "Helper.h" Helper::Helper() { } void Helper::dumpObjectInfo(QObject *obj) { obj->dumpObjectInfo(); }
-
I think the root cause is in qquickheaderview.cpp
Connect to &QAbstractItemModel::headerDataChanged as lambda but disconnect only from class instance.How to notify Qt developers about it?
void QHeaderDataProxyModel::connectToModel() { if (m_model.isNull()) return; connect(m_model, &QAbstractItemModel::headerDataChanged, [this](Qt::Orientation orient, int first, int last) { if (orient != orientation()) return; if (orient == Qt::Horizontal) { emit dataChanged(createIndex(0, first), createIndex(0, last)); } else { emit dataChanged(createIndex(first, 0), createIndex(last, 0)); } }); ...
void QHeaderDataProxyModel::disconnectFromModel() { if (m_model.isNull()) return; m_model->disconnect(this); }
-
I've created bug about it: https://bugreports.qt.io/browse/QTBUG-108610