HorizontalHeaderView not calling headerData() of QAbstractTableModel's child
Solved
QML and Qt Quick
-
Hi, I according to HorizontalHeaderView's doc, it should call headerData() of the model but It's not even calling it in my case
import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Window 2.15 Window { width: 640 height: 480 visible: true title: qsTr("Hello World") id: root HorizontalHeaderView { id: header syncView: tb anchors.top: parent.top // model: KoolModel // specify model explicitly also does not work delegate: Button { text: display } } TableView { id: tb width: parent.width height: parent.height - header.height anchors.top: header.bottom onWidthChanged: forceLayout() model: KoolModel columnWidthProvider: function (_) { return root.width / 3 } delegate: Frame { Label { text: display anchors.centerIn: parent } } } }
here is my model:-
#include <QApplication> #include <QGuiApplication> #include <QTableView> #include <QQmlApplicationEngine> #include <QQmlContext> #include <QAbstractTableModel> #include <QString> #include <map> class Exams : public QAbstractTableModel { private: struct DS { QString title; unsigned int marks; int state; std::vector<int>* questions = nullptr; }; //id and exams std::map<int, DS> exams; public: Exams() { for (int i = 0; i < 10; i++) { DS exam { "Exam" + QString::number(i), 0, (i * 3) / 2, nullptr }; // fill with garbage data for now exams[i] = exam; } } int rowCount(const QModelIndex& parent) const override { return exams.size(); } int columnCount(const QModelIndex& parent) const override { return 3; } QVariant data(const QModelIndex& index, int role) const override { if (role == Qt::DisplayRole) { if (index.column() == 0) return exams.at(index.row()).title; else if (index.column() == 1) return exams.at(index.row()).marks; else if (index.column() == 2) return exams.at(index.row()).state; } qDebug() << "oops"; return QVariant(); } QVariant headerData(int section, Qt::Orientation orientation, int role) const override { qDebug() << "headerData is at least called"; if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { switch (section) { case 0: return QString("Title"); case 1: return QString("Marks"); case 2: return QString("state"); } } return QVariant(); } QHash<int, QByteArray> roleNames() const override { return { { Qt::DisplayRole, "display" } }; } }; int main(int argc, char* argv[]) { Exams exams; // widgets seems to work // QApplication app(argc, argv); // QTableView widget; // widget.setModel(&exams); // widget.show(); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("KoolModel", &exams); const QUrl url(QStringLiteral("qrc:/main.qml")); engine.load(url); return app.exec(); }
I also tested this code with QTableView from widgets module and it seems to work just fine.
-
my bad. I got answer in stack overflow
The problem is caused by a naming conflict between the Button's display property and the role. The solution is to access the role through the model explicitly:
delegate: Button { text: model.display }