View previous topic :: View next topic |
Author |
Message |
Kenji Miyamoto Veteran
Joined: 28 May 2005 Posts: 1452 Location: Looking over your shoulder.
|
Posted: Sun Jun 01, 2008 4:43 pm Post subject: Qt4 Updating TreeModel |
|
|
I've started working with Qt4, but I can't seem to figure out how to get a QTreeView to update with a tree model. So far, these two functions don't work: Code: | void ExecListModel::clearData(void) {
this->beginRemoveRows(QModelIndex(), 0, this->execs.count() - 1);
this->execs.clear();
this->endRemoveRows();
}
void ExecListModel::addData(const Exec * data) {
this->beginInsertRows(QModelIndex(), this->execs.count(), this->execs.count() + 1);
this->execs << data;
this->endInsertRows();
} | The execs QList is updated and everything, but the QTreeView isn't updated past the initial stuff put into the QList. What's the proper way to get a QTreeView to update when its model changes? _________________ [ Kawa-kun, new and improved!! ]
Alex Libman seems to be more of an anarchist than a libertarian. |
|
Back to top |
|
|
d3roga n00b
Joined: 30 Jan 2008 Posts: 14
|
Posted: Mon Jun 02, 2008 8:20 am Post subject: |
|
|
When setData method is called in the QAbstractItemModel it emits dataChanged signal, which informs QTreeView that it should update.
As long as you've set QTreeView to use your model, this should be enough to add new data in it:
Code: |
insertRow(execs.count());
setData(index(execs.count(), 0), data);
|
|
|
Back to top |
|
|
Kenji Miyamoto Veteran
Joined: 28 May 2005 Posts: 1452 Location: Looking over your shoulder.
|
Posted: Mon Jun 02, 2008 4:25 pm Post subject: |
|
|
Where would these calls go?
Here's what I have now, but it still doesn't update the list. It does, however, print the pointers: Code: | void ExecListModel::clearData(void) {
this->beginRemoveRows(QModelIndex(), 0, this->execs.count() - 1);
this->execs.clear();
this->endRemoveRows();
}
void ExecListModel::addData(const Exec * data) {
std::cout << data << std::endl;
this->insertRow(execs.count());
QAbstractListModel::setData(index(execs.count(), 0), data);
this->execs << data;
}
void ExecListModel::setData(QList<const Exec *> & data) {
this->execs = data;
} |
_________________ [ Kawa-kun, new and improved!! ]
Alex Libman seems to be more of an anarchist than a libertarian. |
|
Back to top |
|
|
sno35 Guru
Joined: 15 May 2004 Posts: 334 Location: Paris, France
|
Posted: Mon Jun 02, 2008 8:22 pm Post subject: |
|
|
d3roga wrote: | When setData method is called in the QAbstractItemModel it emits dataChanged signal, which informs QTreeView that it should update.
As long as you've set QTreeView to use your model, this should be enough to add new data in it:
Code: |
insertRow(execs.count());
setData(index(execs.count(), 0), data);
|
|
As I read from http://doc.trolltech.com/4.3/qabstractitemmodel.html#setData
one has to explicitely emit dataChanged in the setData method.
@Kenji from what class do you inherit ? |
|
Back to top |
|
|
Kenji Miyamoto Veteran
Joined: 28 May 2005 Posts: 1452 Location: Looking over your shoulder.
|
Posted: Tue Jun 03, 2008 12:26 am Post subject: |
|
|
I'm inheriting from QAbstractListModel.
Here's some code that produces almost the right result, but around half of the time I get a QTreeView::rowsInserted internal representation of the model has been corrupted, resetting.: Code: | void ExecListModel::clearData(void) {
this->removeRows(0, this->execs.count(), this->index(this->execs.count(), 0));
this->execs.clear();
}
void ExecListModel::addData(const Exec * data) {
this->execs << data;
this->insertRow(this->execs.count(), this->index(this->execs.count(), 0));
QAbstractListModel::setData(this->index(this->execs.count(), 0), QVariant(data));
} | What's really weird is that the first item in the data used in the model is skipped every other time, so the '|ls' in the data below only appears half of the time, alternating regularly: Code: | ls
QTreeView::rowsInserted internal representation of the model has been corrupted, resetting.
QTreeView::rowsInserted internal representation of the model has been corrupted, resetting.
QTreeView::rowsInserted internal representation of the model has been corrupted, resetting.
|ls -> /bin/ls
|lsattr -> /bin/lsattr
|lsdev -> /usr/bin/lsdev
|lsdvd -> /usr/bin/lsdvd
|lshal -> /usr/bin/lshal
|lsmod -> /bin/lsmod |
_________________ [ Kawa-kun, new and improved!! ]
Alex Libman seems to be more of an anarchist than a libertarian. |
|
Back to top |
|
|
d3roga n00b
Joined: 30 Jan 2008 Posts: 14
|
|
Back to top |
|
|
Kenji Miyamoto Veteran
Joined: 28 May 2005 Posts: 1452 Location: Looking over your shoulder.
|
Posted: Tue Jun 03, 2008 3:33 pm Post subject: |
|
|
Actually, I did implement both of those methods before: Code: | bool ExecListModel::insertRows(int position, int rows, const QModelIndex & parent) {
int row;
void * ptr = parent.data().value<void *>();
this->beginInsertRows(QModelIndex(), position, position + rows - 1);
for(row = 0; row < rows; ++row)
if(ptr)
this->execs.insert(position, (const Exec *)ptr);
this->endInsertRows();
return true;
}
bool ExecListModel::removeRows(int position, int rows, const QModelIndex & parent) {
int row;
this->beginRemoveRows(QModelIndex(), position, position + rows - 1);
for(row = 0; row < rows; ++row)
this->execs.removeAt(position);
this->endRemoveRows();
return true;
} | I'll look into QStandardItemModel.
EDIT: Do you know of any examples of QStandardItem than use two columns? _________________ [ Kawa-kun, new and improved!! ]
Alex Libman seems to be more of an anarchist than a libertarian. |
|
Back to top |
|
|
sno35 Guru
Joined: 15 May 2004 Posts: 334 Location: Paris, France
|
Posted: Tue Jun 03, 2008 9:22 pm Post subject: |
|
|
Hi
How your data() and rowCount() look like ? |
|
Back to top |
|
|
Kenji Miyamoto Veteran
Joined: 28 May 2005 Posts: 1452 Location: Looking over your shoulder.
|
Posted: Wed Jun 04, 2008 3:24 pm Post subject: |
|
|
Code: | int ExecListModel::rowCount(const QModelIndex &parent) const {
return this->execs.count();
}
int ExecListModel::columnCount(const QModelIndex &parent) const {
return 2;
}
QVariant ExecListModel::data(const QModelIndex &index, int role) const {
if(!index.isValid())
return QVariant();
else if(index.row() >= this->execs.size() || index.column() >= 2)
return QVariant();
else if(role == Qt::DisplayRole) {
switch(index.column()) {
case 0: return this->execs.at(index.row())->base;
case 1: return this->execs.at(index.row())->fullpath;
default: return QVariant();
}
}
else
return QVariant();
} |
_________________ [ Kawa-kun, new and improved!! ]
Alex Libman seems to be more of an anarchist than a libertarian. |
|
Back to top |
|
|
sno35 Guru
Joined: 15 May 2004 Posts: 334 Location: Paris, France
|
Posted: Wed Jun 04, 2008 7:25 pm Post subject: |
|
|
Hi
You don't want to show a tree, do you ?
So give QmodelIndex() to insertRow as second parameter, because you just want to add a child to the unvisible topmost root == QModelIndex()
Hth |
|
Back to top |
|
|
Kenji Miyamoto Veteran
Joined: 28 May 2005 Posts: 1452 Location: Looking over your shoulder.
|
Posted: Wed Jun 04, 2008 8:50 pm Post subject: |
|
|
I think that fixed the problem, but I'll need to play around with it more before I can verify. _________________ [ Kawa-kun, new and improved!! ]
Alex Libman seems to be more of an anarchist than a libertarian. |
|
Back to top |
|
|
sno35 Guru
Joined: 15 May 2004 Posts: 334 Location: Paris, France
|
Posted: Thu Jun 05, 2008 12:05 am Post subject: |
|
|
I think you were trying to include the data to add in the insertion but at the insertion stage you just have to make room.
You provide data that fills this rooms just when ... data(,,) is called.
Regards |
|
Back to top |
|
|
|