1
votes

I am trying to insert some data in a TableView from a model but I am doing something wrong because the data is not inserted. The table is updated with the columns and rows though.

So I have a GraphicsView where I am drawing some custom GraphicsItems. Each time a new Item is added to the scene the model is supposed to get updated and send a signal to my TableView to insert the data in it as well.

Here I update the model when the new item is added:


    Clothoid *temp = new Clothoid();
        temp->setStartPoint(p1);
        temp->setEndPoint(p2);

        clothoids.append(temp);

        scene->addItem(temp);

        model.setColumnCount(3);
        model.setRowCount(clothoids.size());

        QModelIndex index = model.index(clothoids.size(), 1, QModelIndex());
        model.setData(index, clothoids.last()->startCurvature);
        index = model.index(clothoids.size(), 2, QModelIndex());
        model.setData(index, clothoids.last()->endCurvature);
        index = model.index(clothoids.size(), 3, QModelIndex());
        model.setData(index, clothoids.last()->clothoidLength);

        emit clothoidAdded(&model);


Clothoids being a list of my custom graphicsItems:


QList &lt Clothoid *> clothoids;

The signal is connected to the slot in my main window:

   

    ui->setupUi(this);    
        SpinBoxDelegate delegate;
        ui->clothoidTable->setItemDelegate(&delegate);

        connect(ui->graphicsView, SIGNAL(clothoidAdded(QStandardItemModel*)), ui->clothoidTable, SLOT(onClothoidAdded(QStandardItemModel*)));


where the slot is:


    void TableViewList::onClothoidAdded(QStandardItemModel *model)
        {
            setModel(model);
        }

What am I doing wrong?

1

1 Answers

2
votes

You don't want to be calling setData() directly. Here's a few key steps you need to take:

  • Your model should hold a container (QList, perhaps) of Clothoid pointers (whether it is responsible for freeing the resources or not). The index into the container should map directly to what row it occupies in the view.

  • Your data() and setData() need to be implemented correctly, such that the model knows what Clothoid info goes in each cell for a given row. They should have switch() statements on an enum representing column number, like this:


// in data() after the usual error checking, etc
if(role == Qt::DisplayRole)
    {
    Clothoid* cloth = myListOfClothoids.at(index.row());
    switch(index.column())
        {
        // This enum is defined in the header for the Clothoid class 
        //  and represents the COLUMN NUMBER in which to show the data
        case Clothoid::START: 
            return cloth->startCurvature; // these probably shouldn't be public members btw
        case Clothoid::END:
            return cloth->endCurvature;
        case Clothoid::LENGTH:
            return cloth->clothoidLength;
        }
    }

// in setData()
if(role == Qt::DisplayRole)
    {
    Clothoid* cloth = myListOfClothoids.at(index.row());
    switch(index.column())
        {
        case Clothoid::START: 
            cloth->startCurvature = variant.toWhatever(); 
            break;
        case Clothoid::END:
            cloth->endCurvature = variant.toWhateverElse(); 
            break;
        case Clothoid::LENGTH:
            cloth->clothoidLength = variant.toYetSomethingElse();
            break;
        default:
            return false;
        }
    emit dataChanged(index,index);
    return true;
    }
  1. Your model should have an addClothoid() function. In this function you want to do something like:

int rowIndexFirst = 0; // insert into first row
int rowIndexLast = rowIndexFirst; // only inserting one row/Clothoid
beginInsertRows(QModelIndex(), rowIndexFirst, rowIndexLast);
myListOfClothoids.prepend(newClothoidPtr); // insert clothoid into first index, as well
endInsertRows(); // begin and end take care of signalling the view for you!

I really suggest doing this. Yes, its a lot of work to refactor to this extent, but its worth it, trust me.

Hope this helps.