PDA

View Full Version : QTableView has constant number of rows



tomeks
10th December 2008, 12:33
Hello,

I've got a little problem with QTableView and my own model subclassed from QAbstractTableView. The model is read only, user can change/add data using external dialog. When I add some data, table has still the same number of rows and new data doesn't appear. I know the data is correctly added. When I remove some data from a model, number of rows doesn't change either, last rows of the table just becomes empty. Here is header of my model:


class EmployeesTableModel : public QAbstractTableModel {
Q_OBJECT
public:
EmployeesTableModel( QObject* parent = 0 );
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount ( const QModelIndex & parent = QModelIndex() ) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
void setEmployeesList( std::vector<WPEmployee>* employees );
private:
std::vector<WPEmployee>* _employees;
};

thanks for any help

calmspeaker
10th December 2008, 13:13
please paste your implementation of
int rowCount(const QModelIndex &parent = QModelIndex()) const;
You should emit correct signal when you change(del or edit) the data in the model to notify the view.You could read the qt doc about Model / view programming.

caduel
10th December 2008, 13:33
When you modify (or add to) the underlying data (you passed the std::vector by pointer) the model will obviously not know about it.

So, you have to choices:
i) make all modifications by interacting with your model class (and emit the appropriate signals there; that way you have the possibility to be more precise and say things like "20 rows have been added" - allowing you to keep the current selection...)
ii) modify the underlying data and tell the model afterwards about it, so it can reset itself (QAbstractItemModel::reset(); you will lose the current selection) that way

usually, when dealing with a model, all changes to the models data should be made through the model. otherwise you kinda defeat its purpose...

HTH

tomeks
10th December 2008, 13:36
here is rowcount():
int EmployeesTableModel::rowCount(const QModelIndex &parent ) const {
return _employees->size();
}
columncount() returns 3.

Are you talking about QAbstractItemModel::rowsInserted(), QAbstractItemModel::rowsRemoved() and QAbstractItemModel::dataChanged() signals? Should i really emit these signals, even if i don't change data directly in model? Model contains only pointer to data, which is changed in other dialog. All changed data appears on the view, only number of rows is constant.

tomeks
10th December 2008, 15:15
thanks very much caduel! QAbstractItemModel::reset() solves the problem.

calmspeaker
10th December 2008, 16:29
Are you talking about QAbstractItemModel::rowsInserted(), QAbstractItemModel::rowsRemoved() and QAbstractItemModel::dataChanged() signals?

er, I think the pairs begininsetrows() ,endinsetrows() and beginRemoveRows(), end removerows() are proper functions you should call to insert/remove data. Their implementation emit the proper signals. dataChanged() is mostly used in setData().

Should i really emit these signals, even if i don't change data directly in model? Model contains only pointer to data, which is changed in other dialog. All changed data appears on the view, only number of rows is constant.

I guess you try to avoid let the model become a editable model to make things easier.But the way you choose is not efficent esp when your data is large. Becasue reset() really tell the view to do much more things than you need. I suggest you implement



Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole);
bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex());
bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex());
to achieve your goal. They allow you to edit your model flexiblely.