Qt6 TableView + TableModel + 外側スクロールバー常時表示の完全実装ガイド
Qt6 の TableView は Qt5 時代と大きく仕様が変わっており、
TableViewColumn や ListModel.append() が使えず、
さらに TableModel の import も Qt6 では別モジュールになっています。
この記事では、Qt6(6.3+)で動作する 新 TableView + TableModel を使い、
5×30 のテーブルにスクロールバーを外側に配置する方法をまとめます。
1. Qt6 の TableModel は Qt.labs.qmlmodels にある
Qt6 の TableModel は Qt.labs.qmlmodels にあります。
Qt5 時代の QtQml.Models とは別物なので注意。
2. TableModel のデータは rows: で直書きできる
appendRow() を使わず、次のように rows プロパティに直接配列で書けます。
TableModel {
TableModelColumn { display: "c1" }
TableModelColumn { display: "c2" }
TableModelColumn { display: "c3" }
TableModelColumn { display: "c4" }
TableModelColumn { display: "c5" }
rows: [
{ c1: "R0C1", c2: "R0C2", c3: "R0C3", c4: "R0C4", c5: "R0C5" },
{ c1: "R1C1", c2: "R1C2", c3: "R1C3", c4: "R1C4", c5: "R1C5" },
...
]
}
3. Qt6 の TableView は delegate 内でセルを描画する
Qt5 の TableViewColumn は Qt6 では廃止。
Qt6 の TableView は delegate の中でセルを描画します。
4. スクロールバーは policy: ScrollBar.AlwaysOn で常時表示
policy: ScrollBar.AlwaysOn
これでスクロール可能かどうかに関係なく常に表示されます。
5. 完成コード
import QtQuick
import QtQuick.Controls
import Qt.labs.qmlmodels // ★ Qt6 の TableModel はこれ
Item {
width: 400
height: 300
// ★ データ直書きの TableModel(appendRow 不使用)
TableModel {
id: tableModel
TableModelColumn { display: "c1" }
TableModelColumn { display: "c2" }
TableModelColumn { display: "c3" }
TableModelColumn { display: "c4" }
TableModelColumn { display: "c5" }
rows: [
{ c1: "R0C1", c2: "R0C2", c3: "R0C3", c4: "R0C4", c5: "R0C5" },
{ c1: "R1C1", c2: "R1C2", c3: "R1C3", c4: "R1C4", c5: "R1C5" },
{ c1: "R2C1", c2: "R2C2", c3: "R2C3", c4: "R2C4", c5: "R2C5" },
{ c1: "R3C1", c2: "R3C2", c3: "R3C3", c4: "R3C4", c5: "R3C5" },
{ c1: "R4C1", c2: "R4C2", c3: "R4C3", c4: "R4C4", c5: "R4C5" },
{ c1: "R5C1", c2: "R5C2", c3: "R5C3", c4: "R5C4", c5: "R5C5" },
{ c1: "R6C1", c2: "R6C2", c3: "R6C3", c4: "R6C4", c5: "R6C5" },
{ c1: "R7C1", c2: "R7C2", c3: "R7C3", c4: "R7C4", c5: "R7C5" },
{ c1: "R8C1", c2: "R8C2", c3: "R8C3", c4: "R8C4", c5: "R8C5" },
{ c1: "R9C1", c2: "R9C2", c3: "R9C3", c4: "R9C4", c5: "R9C5" }
// ★ 必要なら R10〜R29 を追加して 30 行にできます
]
}
// -------------------------
// TableView 本体(Qt6)
// -------------------------
TableView {
id: table
anchors {
top: header.bottom
left: parent.left
right: vbar.left
bottom: hbar.top
}
model: tableModel
clip: true
rowSpacing: 1
columnSpacing: 1
// 列幅
columnWidthProvider: function(col) { return 100 }
delegate: Rectangle {
implicitWidth: 100
implicitHeight: 30
color: (row % 2 === 0) ? "#f0f0f0" : "#ffffff"
border.color: "#cccccc"
Text {
text: display
anchors.centerIn: parent
}
}
ScrollBar.vertical: vbar
ScrollBar.horizontal: hbar
}
// -------------------------
// 固定ヘッダー
// -------------------------
HorizontalHeaderView {
id: header
syncView: table
anchors {
top: parent.top
left: parent.left
right: vbar.left
}
height: 30
}
// -------------------------
// 右側スクロールバー(常時表示)
// -------------------------
ScrollBar {
id: vbar
orientation: Qt.Vertical
policy: ScrollBar.AlwaysOn // ★ 常時表示
anchors {
top: header.bottom
bottom: hbar.top
right: parent.right
}
width: 14
}
// -------------------------
// 下側スクロールバー(常時表示)
// -------------------------
ScrollBar {
id: hbar
orientation: Qt.Horizontal
policy: ScrollBar.AlwaysOn // ★ 常時表示
anchors {
left: parent.left
right: vbar.left
bottom: parent.bottom
}
height: 14
}
}
まとめ
TableModel を使いたい import Qt.labs.qmlmodels
データを直書きしたい rows: [ {...}, {...} ]
TableViewColumn を使いたい Qt6 では廃止。delegate で描画
スクロールバーを外側に置きたい ScrollBar.vertical: vbar
スクロールバー常時表示 policy: ScrollBar.AlwaysOn
ヘッダー固定 HorizontalHeaderView
Qt6 の TableView は Qt5 と別物なので、
正しいモジュールと正しい書き方を使うことが重要です。