Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

HorizontalHeaderView not calling headerData() of QAbstractTableModel's child



  • 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
    }
    


  • 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
    }