I'm trying to get TableView (the new one from pure qml introdudced in qt5.12) with column which resize them dynamically to fill extra available space but It's not working
here is my minimal reproducible example:-
main.qml:-
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15
Window {
id: window
width: 640
height: 480
visible: true
title: qsTr("Hello World")
TableView {
anchors.fill: parent
model: KoolModel
// columnWidthProvider: function (_) { return parent.width/3} // Method 1, Does not work
delegate: Frame {
// implicitWidth: parent.width/3 //Method 2, Does not work
implicitWidth: 640/3 // works but not the solution for my problem
Label {
text: display
anchors.centerIn: parent
}
}
}
}
If I execute this code, I get following:-
it is the desired output but when I resize the window the columns should expand which does not happen due to hardcoding the implicitWidth
if I use columnWidthProvider: function (_) { return parent.width/3}
then I get nothing, just a white window:-
and If I try to use binding like this implicitWidth: parent.width/3
I get following:-
main.cpp:-
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "models/exams.hpp"
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
Models::Exams exams;
engine.rootContext()->setContextProperty("KoolModel", &exams);
const QUrl url(QStringLiteral("qrc:/main.qml"));
engine.load(url);
return app.exec();
}
models/exam.cpp
#pragma once
#include <QAbstractTableModel>
#include <QString>
#include <map>
namespace Models {
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();
// QAbstractItemModel interface
int rowCount(const QModelIndex& parent) const override;
int columnCount(const QModelIndex& parent) const override;
QVariant data(const QModelIndex& index, int role) const override;
// QAbstractItemModel interface
public:
QHash<int, QByteArray> roleNames() const override;
};
} //end namespace Models
models/exam.cpp:-
#include "exams.hpp"
namespace Models {
Exams::Exams()
{
for (int i = 0; i < 200; i++) { //fill garbage data for now
DS exam {
"Exam" + QString::number(i),
0,
(i * 3) / 2,
nullptr
};
exams[i] = exam;
}
exams[2] = {
"Exam" + QString::number(10000000324),
0,
10,
nullptr
};
}
int Exams::rowCount(const QModelIndex& parent) const
{
return exams.size();
}
int Exams::columnCount(const QModelIndex& parent) const
{
return 3;
}
QVariant Exams::data(const QModelIndex& index, int role) const
{
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;
}
return QVariant();
}
QHash<int, QByteArray> Exams::roleNames() const
{
return { { Qt::DisplayRole, "display" } };
}
} // end namepsace Models
I'm using Qt 5.15 from Archlinux repos
For performance reasons, TableView does not re-calculate its row height or column width unless absolutely necessary. But you can force it by calling forceLayout()
whenever the width changes.
onWidthChanged: forceLayout()