Data from model not inserted in QTableView
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.se开发者_Go百科tData(index, clothoids.last()->clothoidLength); emit clothoidAdded(&model);
Clothoids being a list of my custom graphicsItems:
QList < 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?
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()
andsetData()
need to be implemented correctly, such that the model knows what Clothoid info goes in each cell for a given row. They should haveswitch()
statements on anenum
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;
}
- 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.
精彩评论