Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qt Quick Application crashing on updating the ListView using QAbstractListModel class



  • I am trying to update the Listview from c++ data model which is the subclass of QAbstractListModel.
    When the run the program the application is crashing immediately with this Error

    90461094-19dd-4dbc-8c49-84a74684b7f7-image.png

    During debugging I observed that after calling the below functions the application is getting crashed , I think this is related to updating the listview

    QHash<int, QByteArray> roleNames() const;

    I have added the required snippsets of the code below

    ================wifi_model.h=================================

    #ifndef WIFI_MODEL_H
    #define WIFI_MODEL_H

    #include <QAbstractListModel>

    class WiFi_data{

    QString m_name ;
    

    public:
    WiFi_data();
    WiFi_data(const QString &name);
    QString getName() const;
    void setName(const QString &value);
    };

    class WiFi_model : public QAbstractListModel
    {
    Q_OBJECT

    public:

    enum WiFi_properties{
        name = Qt::UserRole + 1,
    };
    
    explicit WiFi_model(QObject *parent = nullptr);
    
    // Basic functionality:
    QModelIndex index(int row, int column,
                      const QModelIndex &parent = QModelIndex()) const override;
    QModelIndex parent(const QModelIndex &index) const override;
    
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    //    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    
    // Get data:
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    // Remove data:
    bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
    // Add data:
    void appendRows(const WiFi_data &data);
    
    QHash<int,QByteArray> roleNames() const;
    

    private:

    QList<WiFi_data> wifi_model_list;
    

    };

    #endif // WIFI_MODEL_H

    ================wifi_model.cpp=================================

    #include "wifi_model.h"

    WiFi_data::WiFi_data()
    {

    }

    WiFi_data::WiFi_data(const QString &name)
    :m_name(name)
    {

    }

    QString WiFi_data::getName() const
    {
    return m_name;
    }

    void WiFi_data::setName(const QString &value)
    {
    m_name = value;
    }

    WiFi_model::WiFi_model(QObject *parent)
    : QAbstractListModel(parent)
    {
    }

    QModelIndex WiFi_model::index(int row, int column, const QModelIndex &parent) const
    {
    // FIXME: Implement me!
    }

    QModelIndex WiFi_model::parent(const QModelIndex &index) const
    {
    // FIXME: Implement me!
    }

    int WiFi_model::rowCount(const QModelIndex &parent) const
    {
    Q_UNUSED(parent);
    return wifi_model_list.count();
    }

    //int WiFi_model::columnCount(const QModelIndex &parent) const
    //{
    // if (!parent.isValid())
    // return 0;

    // // FIXME: Implement me!
    //}

    QVariant WiFi_model::data(const QModelIndex &index, int role) const
    {

    if (index.row() < 0 || index.row() >= wifi_model_list.count())
        return QVariant();
    
    const WiFi_data &model_data = wifi_model_list[index.row()];
    if (role == name)
        return model_data.getName();
    
    return QVariant();
    

    }

    bool WiFi_model::removeRows(int row, int count, const QModelIndex &parent)
    {
    beginRemoveRows(parent, row, row + count - 1);
    // FIXME: Implement me!
    endRemoveRows();
    }

    void WiFi_model::appendRows(const WiFi_data &data)
    {
    beginInsertRows(QModelIndex(), rowCount(), rowCount());
    wifi_model_list << data;
    endInsertRows();

    }

    QHash<int, QByteArray> WiFi_model::roleNames() const
    {
    QHash<int, QByteArray> roles;
    roles[name] = "name";

    return roles;
    

    }

    ==============main.cpp========================================

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    #include "wifi_model.h"

    int main(int argc, char *argv[])
    {
    #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    #endif

    QGuiApplication app(argc, argv);
    
    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    
    WiFi_model m_wifi_model;
    
    m_wifi_model.appendRows(WiFi_data("name"));
    m_wifi_model.appendRows(WiFi_data("data"));
    
    QQmlContext* context = engine.rootContext();
    context->setContextProperty("wifi_model", &m_wifi_model);
    
    engine.load(url);
    
    
    return app.exec();
    

    }

    ===================main.qml=================================

    import QtQuick 2.11
    import QtQuick.Window 2.11
    import QtQuick.Controls 2.15

    Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    GroupBox {
        id: groupBox
        x: 14
        y: 13
        width: 318
        height: 397
        title: qsTr("Group Box")
    
        ListView {
    
            model : wifi_model
            delegate: Text {
                text: name
                anchors.verticalCenter: parent.verticalCenter
                font.bold: true
            }
    
            onCountChanged: console.log("count changed: " + count)
        }
    }
    

    }


  • Moderators

    @James-A
    start with QtCreator debugger and post the full stack trace when it crashes.



  • @raven-worx

    I added the full stack trace below

    1 QQmlDMCachedModelData::metaCall(QMetaObject::Call, int, void * *) 0x7fffe8114b83
    2 loadProperty(QV4::ExecutionEngine *, QObject *, QQmlPropertyData const&) [clone .constprop.350] 0x7ffff71b99ce
    3 QV4::QObjectWrapper::getQmlProperty(QV4::ExecutionEngine *, QQmlContextData *, QObject *, QV4::String *, QV4::QObjectWrapper::RevisionMode, bool *, QQmlPropertyData * *) 0x7ffff71ba7da
    4 QV4::QQmlContextWrapper::getPropertyAndBase(QV4::QQmlContextWrapper const *, QV4::PropertyKey, QV4::Value const *, bool *, QV4::Value *, QV4::Lookup *) 0x7ffff7193954
    5 QV4::QQmlContextWrapper::resolveQmlContextPropertyLookupGetter(QV4::Lookup *, QV4::ExecutionEngine *, QV4::Value *) 0x7ffff71940ed
    6 QV4::Moth::VME::interpret(QV4::CppStackFrame *, QV4::ExecutionEngine *, const char *) 0x7ffff71d53bc
    7 QV4::Moth::VME::exec(QV4::CppStackFrame *, QV4::ExecutionEngine *) 0x7ffff71d958b
    8 QV4::Function::call(QV4::Value const *, QV4::Value const *, int, QV4::ExecutionContext const *) 0x7ffff716e1e5
    9 QQmlJavaScriptExpression::evaluate(QV4::CallData *, bool *) 0x7ffff72ef43a
    10 QQmlBinding::evaluate(bool *) 0x7ffff72f4b47
    11 QQmlNonbindingBinding::doUpdate(QQmlJavaScriptExpression::DeleteWatcher const&, QFlagsQQmlPropertyData::WriteFlag, QV4::Scope&) 0x7ffff72f9805
    12 QQmlBinding::update(QFlagsQQmlPropertyData::WriteFlag) 0x7ffff72f6363
    13 QQmlObjectCreator::finalize(QQmlInstantiationInterrupt&) 0x7ffff7306442
    14 QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt&) 0x7ffff72953e9
    15 QQmlEnginePrivate::incubate(QQmlIncubator&, QQmlContextData *) 0x7ffff7295904
    16 QQmlDelegateModelPrivate::object(QQmlListCompositor::Group, int, QQmlIncubator::IncubationMode) 0x7fffe8125252
    17 QQmlDelegateModel::object(int, QQmlIncubator::IncubationMode) 0x7fffe8125572
    18 QQuickItemViewPrivate::createItem(int, QQmlIncubator::IncubationMode) 0x7fffe865288f
    19 QQuickListViewPrivate::addVisibleItems(double, double, double, double, bool) 0x7fffe86617f8
    20 QQuickItemViewPrivate::refill(double, double) 0x7fffe8653c3a
    21 QQuickItemView::componentComplete() 0x7fffe8659088
    22 QQmlObjectCreator::finalize(QQmlInstantiationInterrupt&) 0x7ffff73067c1
    23 QQmlComponentPrivate::complete(QQmlEnginePrivate *, QQmlComponentPrivate::ConstructionState *) 0x7ffff728e5f1
    24 QQmlComponentPrivate::completeCreate() 0x7ffff7290ef7
    25 QQmlComponent::create(QQmlContext *) 0x7ffff728e0db
    26 QQmlApplicationEnginePrivate::finishLoad(QQmlComponent *) 0x7ffff72fb5cc
    27 QQmlApplicationEnginePrivate::startLoad(QUrl const&, QByteArray const&, bool) 0x7ffff72fb7e6
    28 QQmlApplicationEngine::load(QUrl const&) 0x7ffff72fba1d
    29 main main.cpp 30 0x555555557c5c


  • Moderators

    @James-A
    i dont think that the code you've posted is causing this issue.

    The only code which doesn't make sense is the line

    anchors.verticalCenter: parent.verticalCenter

    in your delegate.



  • @raven-worx

    I tried changing the delegate to delegate: Text { text: name }
    But the issue is persisting


  • Moderators

    @James-A
    as i said, i don't think that the code you've posted is causing this issue, at least i don't spot an issue.
    Try a full rebuild.

    If the issue persists, try removing single items to check which Item is causing it.

    Also your ListView has no size set.



  • @raven-worx

    I tried deleting the output folder and then rebuild gain , and also tried commenting out individually the code under WiFi_model, from that what I observed is when I remove the below line from the "roleNames()" functions the application is starting , but not updating the data on the ListView

    roles[name] = "name";

    92aa3d0d-e82e-4705-95c1-c6e2d23de101-image.png

    Again when I try adding it back , the application gets crashed
    So I found the line of code which is causing the problem , but not sure why it is causing the crash and what I am missing in it

    And I also set the ListView size as below

    anchors.fill: parent


  • Moderators

    @James-A
    strange.
    Does it work when you rename the enum value from name to e.g. NameRole?

    QHash<int, QByteArray> WiFi_model::roleNames() const
    {
    QHash<int, QByteArray> roles;
    roles[NameRole] = QByteArrayLiteral("name");
    return roles;
    }
    

  • Qt Champions 2017

    Can u also try removing the columnCount implementation completely ? This is not required. Some times this is also a issue.



  • @raven-worx

    I changed the roleNames() function implementation as suggested above.

    @dheerendra

    I completely removed the commented columnCount() function

    But there is no change , still the error exist


  • Qt Champions 2017

    Issue is coming from index() and parent() method. Comment them.
    Also qml code needs correction.
    This should work.

    GroupBox {
            id: groupBox
            anchors.fill: parent
            ListView {
                anchors.fill: parent
                model : wifi_model
                delegate: Text {
                    text: name
                    width: 300;height: 40
                    font.bold: true
                }
                onCountChanged: console.log("count changed: " + count)
            }
        }
    


  • @dheerendra

    Thanks for pointing it out. Yes it was due to index() and parent() . I removed it completely
    Now the application is running

    45f07dd4-29fb-4dd2-b128-cb8de0e69065-image.png


Log in to reply