How to implement setHeaderData in a subclass of QAbstractTableModel?
-
@jdent
Did you look at the docs page? Did you follow the Sorting section code?Although it does no harm, with what is in your
lessThan()
at present I don't think you needed to override it. QSortFilterProxyModel::lessThan() already handles the types you have coded for. But if you were to change the behaviour that's where you would do it. -
Again, sorting is ok - and you are right not needed to subclass it... The problem I am having is that the QHeaderView does not respond to clicking the mouse!! So, I cannot change the column used to sort at runtime!!
Yet I have:
ui.tableView->setHorizontalHeader(new QHeaderView{ Qt::Horizontal }); ui.tableView->setSortingEnabled(true);
And yes I read the Sorting section code!
-
At runtime, sort() and lessThan() get called at the beginning (when below code executes) but not when I click the header... also the column's sort indicator is not responding to my clicks and sorting is not happening when I click the header only after the following code executes
When this code executes, sort() is called once and lessThan() is called many times (proportional to number of rows):
ui.tableView->setSortingEnabled(true);
but not anymore afterwards !
-
@jdent said in How to implement setHeaderData in a subclass of QAbstractTableModel?:
but not anymore afterwards !
Why should it - once it's sorted why would it need to sort it again?
Please provide a minimal, compilable example of your problem.
-
@jdent said in How to implement setHeaderData in a subclass of QAbstractTableModel?:
but not anymore afterwards !
Not "anymore afterwards" when you do what?
The behaviour I would expect is:
-
The first time you click on a column it should do a sort on that column. You should then see the "sort indicator" on that column's header being shown pointing up or down, to indicate it is sorted on that column in a certain direction.
-
If you click on that column again it should reverse sort, and the indicator should reverse its direction. I am not sure whether it actually issues a
sort()
in this case, since it already has it sorted it could just reverse the order or all the rows showing in the view. Or it may re-sort()
in the opposite direction. -
If you click on a different column it should
sort()
on that new column, and move the sort indicator to show on the new column.
-
-
This does not happen:
"The first time you click on a column it should do a sort on that column. You should then see the "sort indicator" on that column's header being shown pointing up or down, to indicate it is sorted on that column in a certain direction.
If you click on that column again it should reverse sort, and the indicator should reverse its direction. I am not sure whether it actually issues a sort() in this case, since it already has it sorted it could just reverse the order or all the rows showing in the view. Or it may re-sort() in the opposite direction.
If you click on a different column it should sort() on that new column, and move the sort indicator to show on the new column."
the header view does not respond to mouse clicks at all!
Could it be that the model is read only?This is the model:
class VectorModel : public QAbstractTableModel { Q_OBJECT std::unique_ptr<AbstractCollection> collection; std::vector<QVariant> headers; public: VectorModel(std::unique_ptr<AbstractCollection> coll, QObject *parent = nullptr) : collection(std::move(coll)), QAbstractTableModel(parent) { collection->load(); headers.resize(collection->coll_count()); } ~VectorModel() = default; void refresh() { collection->load(); } int rowCount(const QModelIndex& parent) const override { //if(parent.isValid()) // return 0; return collection->row_count(); } int columnCount(const QModelIndex& parent) const override { return collection->coll_count(); } QVariant data(const QModelIndex& index, int role) const override { using std::get; if(role != Qt::DisplayRole && role != Qt::EditRole) { return QVariant(); } return collection->data(index); } bool setHeaderData(int section, Qt::Orientation orientation, const QVariant& value, int role) override { if (orientation == Qt::Horizontal && role == Qt::EditRole) { headers[section] = value; headerDataChanged(orientation, section, section); return true; } return false; } QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override { if (orientation == Qt::Horizontal) { if (role == Qt::DisplayRole) return headers[section]; return QVariant{}; } return QVariant{}; } };
And this is the preparation code:
VectorModel* model = new VectorModel{ std::unique_ptr<AbstractCollection>(new PersistentCollection{ storage(), select(columns(&Claim::id, &Claim::amount, &Claim::start_date))})}; QSortFilterProxyModel* proxy = new QSortFilterProxyModel{ this }; proxy->setSourceModel(model); ui.tableView->setHorizontalHeader(new QHeaderView{ Qt::Horizontal }); ui.tableView->setSortingEnabled(true); ui.tableView->setModel(proxy); bool ok = proxy->setHeaderData(0, Qt::Horizontal, QObject::tr("ID")); ok = proxy->setHeaderData(1, Qt::Horizontal, QObject::tr("Amount")); ok = proxy->setHeaderData(2, Qt::Horizontal, QObject::tr("Start Date"));
Is that enough code to help me figure out what is hapenning?
-
This is not minimal nor compilable - can't test your code until you simplify it.
Also why do you set a new QHeaderView?? -
because I wasn't seeing a QHeaderView
Then you removed it in the design mode as I already told you but we can't tell...
This works fine for me, fix your code until it works or it's compilable for us - don't know what's so hard to create a minimal, compilable example...:
int main(int argc, char* argv[]) { QApplication app(argc, argv); auto model = new QStandardItemModel; for (int i = 0; i < 10; ++i) model->appendRow(new QStandardItem(QString::number(i))); QTableView tv; tv.setModel(model); tv.setSortingEnabled(true); tv.show(); return app.exec(); }
-