Question

Trying to implement a custom model for my qlistview. I've been reading the links of past posts similar to to mine but I haven't been able to get it to work.

I wanted to list my my object that should be created dynamically by the user by clicking on the add button. To remove the item on the listview, the user should select the item then click on the remove button.

Edit - I'm trying to create a qlistview with a custom model that inherits from QAbstractListModel. The qlistview will display Qlist, all items should list in the qlistview. I would also like the user to create and add a new MyCustomObject to the Qlist.

I tried following the examples and posts that I can find through google search but at this moment I'm lost.

The application crashes when the add button is clicked.

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QList<MyCustomObject*> *m_list = new QList<MyCustomObject*>;

    CustomListModel *lmodel = new CustomListModel(this);

    MyCustomObject *object = new MyCustomObject(this);

    m_list->append(object);

    ui->listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    ui->listView->setEditTriggers(QAbstractItemView::NoEditTriggers);

    lmodel->setmylist(m_list);

    //Initialize the Listview
    ui->listView->setModel(lmodel);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_addpushButton_clicked()
{
    MyCustomObject *object = new MyCustomObject(this);

    lmodel->AddmycustomObject(object);
}

void MainWindow::on_removepushButto_clicked()
{

}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QListView>
#include <customlistmodel.h>
#include "mycustomobject.h"


namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_addpushButton_clicked();

    void on_removepushButto_clicked();

private:
    Ui::MainWindow *ui;
    QList<MyCustomObject*> *m_list;
    CustomListModel *lmodel;


};

#endif // MAINWINDOW_H

customlistmodel.cpp

#include "customlistmodel.h"

CustomListModel::CustomListModel(QObject *parent) :
    QAbstractListModel(parent)
{
}
QVariant CustomListModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    if (index.row() >= Model_list->size())
        return QVariant();

    if (role == Qt::DisplayRole)
       return QVariant(QString("row [%1]").arg((Model_list->at(index.row()))->GetName() ));
    else
        return QVariant();
}
int CustomListModel::rowCount(const QModelIndex &parent) const
{
        Q_UNUSED(parent);
        return Model_list->size();
}
//bool CustomListModel::insertRows(int row, int count, const QModelIndex &parent)
//{
//    beginInsertRows(QModelIndex(), row, row+count-1);


//    endInsertRows();

//    return true;
//}


//bool CustomListModel::removeRows(int row, int count, const QModelIndex &parent)
//{
//    beginRemoveRows(QModelIndex(), row, row+count-1);


//    endRemoveRows();

//    return true;

//}





//bool CustomListModel::setData(const QModelIndex &index, const QVariant &value, int role)
//{
//   if (index.isValid() && role == Qt::EditRole) {

//      MyCustomObject *item = Model_list->at(index.row());
//      item->SetNam(value.toString());

//     // Model_list->at(index.row())->SetNam(value.toString());
//      emit dataChanged(index,index);
//      return true;
//   }
//   return false;

//}
//Custom Methods
void CustomListModel::setmylist(QList<MyCustomObject*> *list)
{
    beginResetModel();

    Model_list = list;

    endResetModel();
    reset();

}
void CustomListModel::AddmycustomObject(MyCustomObject *object)
{

    int first = Model_list->count();
    int last = first;

          beginInsertRows(QModelIndex(), first, last);
          Model_list->append(object);
          endInsertRows();

}

CustomListModel.h

#ifndef CUSTOMLISTMODEL_H
#define CUSTOMLISTMODEL_H

#include <QAbstractListModel>
#include <QList>
#include "mycustomobject.h"

class CustomListModel : public QAbstractListModel
{
    Q_OBJECT
public:
    explicit CustomListModel(QObject *parent = 0);
    QVariant data(const QModelIndex &index, int role) const;
    int rowCount(const QModelIndex &parent) const;
   // bool setData(const QModelIndex &index, const QVariant &value, int role);

   // bool insertRows(int row, int count, const QModelIndex &parent);
    //bool removeRows(int row, int count, const QModelIndex &parent);

    //Custom Methods
    void setmylist(QList<MyCustomObject*> *list);
    void AddmycustomObject(MyCustomObject *object);
private:
    QList<MyCustomObject*>* Model_list;

signals:

public slots:

};
#endif // CUSTOMLISTMODEL_H

MyCustomObject.h

#ifndef MYCUSTOMOBJECT_H
#define MYCUSTOMOBJECT_H

#include <QObject>

class MyCustomObject : public QObject
{
    Q_OBJECT
public:
    explicit MyCustomObject(QObject *parent = 0);
    QString Name;
    QString GetName() {return Name;}
    void SetNam(QString Value){ Name = Value;}
signals:

public slots:

};

#endif // MYCUSTOMOBJECT_H

mycustomobject.cpp

#include "mycustomobject.h"

MyCustomObject::MyCustomObject(QObject *parent) :
    QObject(parent)
{
    this->Name = "TestName";
}

main.cpp

#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.ui enter image description here

Was it helpful?

Solution

@DanielCastro touched on this in the main comment, but I am expanding on it as I think it might be your actual crash.

In your MainWindow, you declare a private member for the model:

private:
    ...
    CustomListModel *lmodel;

But in your MainWindow constructor, you initialize a brand new model and set it on your view:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ...
    // Not actually initializing the private member
    CustomListModel *lmodel = new CustomListModel(this);
    ...

    lmodel->setmylist(m_list);

    //Initialize the Listview
    ui->listView->setModel(lmodel);
}

This leaves your private lmodel as a null pointer. Then you have a slot that tries to access it:

void MainWindow::on_addpushButton_clicked()
{
    MyCustomObject *object = new MyCustomObject(this);
    // CRASH because you access a NULL pointer
    lmodel->AddmycustomObject(object);
}

So the fix would probably be to make sure you are initializing the private member and not a brand new model in the MainWindow constructor:

lmodel = new CustomListModel(this);

You are doing the same thing with your m_list, so also:

m_list = new QList<MyCustomObject*>;

it also seems like you might have potential crashes now or down the line from using a QList pointer instead of just a QList in your classes. I would think it would be better to make sure your model has a fully initialized list object, and then you can set into it or clear it from other lists.

private:
    QList<MyCustomObject*> Model_list;

And then you would pass them like:

void setmylist(QList<MyCustomObject*> &list);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top