QAbstractListModel > call to endInsertRows() from NON Qt (GUI) thread results in crash



  • Hi,

    I have a derived class from QAbstractListModel and I want to add elements to this list. So I do the following:

    @
    void addElement()
    beginInsertRows(QModelIndex(), myList.count(), myList.count());
    myList.push_back(myElement);
    endInsertRows();
    @

    This works when I call addElement() from the Qt main thread. When I call this function from a NON Qt thread (normal pthread) the application crashes on endInsertRows() method.

    I have read that endInsertRows() emits a signal and this shouldn't be done from a NON Qt thread. For now I have "fixed" this by connecting addElement() to a signal that's used in the NON Qt thread and using Qt:QueuedConnection option.

    Is there another way to do this?



  • That seems a reasonable solution to me. If you know that you will always call this function from another thread then you can hide the use of signals/slots/queued connections within the class:

    @
    MyModel::MyModel( QObject* parent )
    : QAbstractListModel( parent )
    {
    connet( this, SIGNAL( addElementRequested() ), this, SLOT( doAddElement() ) );
    ...
    }

    void MyModel::addElement()
    {
    emit addElementRequested();
    }

    void MyModel::doAddElement()
    {
    beginInsertRows(QModelIndex(), myList.count(), myList.count());
    myList.push_back(myElement);
    endInsertRows();
    }
    @

    where doAddElement() is a private slot. WIth the above if you call addElement() from the main GUI thread it will be synchronous as it will use a direct connection. If you call it from a worker thread then it will use a queued connection and happen asynchronously.

    HTH.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.