How to implement setHeaderData in a subclass of QAbstractTableModel?
-
Hi,
I have a subclass of QAbstractTableModel for which I am implementing setHeaderData but it is not doing anything (I don't see the header changed)
bool ok = model->setHeaderData(0, Qt::Horizontal, QObject::tr("ID")); ok = model->setHeaderData(1, Qt::Horizontal, QObject::tr("Amount"));
What do I need to do to show the header titles on the QTableView?
Currently my implementation of the function is:
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant& value, int role) override { headerDataChanged(orientation, section, section); // emit signal! return true; }
Regards,
Juan -
@jdent said in How to implement setHeaderData in a subclass of QAbstractTableModel?:
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant& value, int role)
Don't you think you should store (and latert return within headerData()) the values et somewhere?
-
@Pl45m4 my headerData() is currently:
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override { if (orientation == Qt::Horizontal) { if (role == Qt::DisplayRole) return QVariant{ tr("Num %1").arg(section) }; return "?"; } return "---"; }
I know it isn't correct... please some help.
Regards,
Juan -
@jdent said in How to implement setHeaderData in a subclass of QAbstractTableModel?:
I know it isn't correct... please some help.
As I already set - you should return the data which was set through setHeaderData() - how should it work otherwise?
-
@Christian-Ehrlicher but what should I return when role is Qt::DisplayRole and when role is otherwise?
Just imagine for now - to simplify the example - that I have no setHeaderData() overload and that I just want "Num 0" for column 0 and "Num 1" for column 1. What should I return for each value of role? -
@jdent said in How to implement setHeaderData in a subclass of QAbstractTableModel?:
I just want "Num 0" for column 0 and "Num 1" for column 1. What should I return for each value of role?
You already return this.
what do I need to call in QTableView to display the header of the model?
Nothing - except you've hidden the header by yourself.
-
@Christian-Ehrlicher "You already return this." No, I don't see any header!!
"what do I need to call in QTableView to display the header of the model?
Nothing - except you've hidden the header by yourself." What do you mean, I have hidden the header??
-
@jdent
Your code usessetHeaderData()
to explicitly set some header.
From that method you need to save/store that value. Somewhere in your subclass.
Then yourheader()
method needs to retrieve that and return it.
This is what a model like, say,QStandardItemModel
will do for you.
When you use your ownQAbstractTableModel
you have to implement this. In your own member variable structure. For all roles you wish to allow the caller to store data in header.
If you do not need to allow callers to set the header data, e.g. you can calculate what you want, then you don't need asetHeaderData()
or storage, you can just writeheader()
to compute and return values.
It's the same principle as what you do withsetData()
anddata()
in your subclassedQAbstractTableModel
, only done separately for the header data. -
@jdent said in How to implement setHeaderData in a subclass of QAbstractTableModel?:
QAbstractTableModel has no header() method nor its superclass!!
It's a typo - it's headerData() as you already found out...
-
@jdent
Start by correcting your code, your last 2return
statements are not acceptable for any role.if (orientation == Qt::Horizontal) { if (role == Qt::DisplayRole) return QVariant{ tr("Num %1").arg(section) }; return QVariant(); } return QVariant();
Then confirm with a breakpoint/debug statement that your
headerData()
is getting called, and report back.I assume you have a
QHeaderView
in yourQTableView
to see the headers? -
But now I cannot sort by column!!
and I haveVectorModel* model = new VectorModel{ std::unique_ptr<AbstractCollection>(new PersistentCollection{ storage(), select(columns(&Claim::id, &Claim::amount))})}; QSortFilterProxyModel* proxy = new QSortFilterProxyModel{ this }; proxy->setSourceModel(model); ui.tableView->setModel(proxy); ui.tableView->setHorizontalHeader(new QHeaderView{ Qt::Horizontal }); ui.tableView->setSortingEnabled(true); ui.tableView->setSelectionMode(QAbstractItemView::SingleSelection);
-
Anyway I needed to modify sorting: how do I take control of it? For instance if the column has text then alphanumerical sorting must be done and if it is numeric, then the text in the cell must be converted to numeric and the order set numerically! How is this done?
-
@jdent
You should use a QSortFilterProxyModel for displaying your model sorted.treeView = new QTreeView; model = new YourModel; proxyModel = new QSortFilterProxyModel(this); proxyModel->setSourceModel(model); treeview->setModel(proxyModel);
Then you do sorting (and optionally filtering too) in the proxy model code.