You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt Quick中TableView不可见问题及布局实现需求

问题解决:QML布局中TableView无法显示并拉伸至底部

问题场景

需要搭建的界面结构:

  • 顶部并排显示TextField和Button
  • HorizontalHeaderView占满窗口宽度
  • TableView占满窗口宽度并延伸至窗口底部

当前问题:TextField和Button正常显示,HorizontalHeaderView仅部分可见,TableView完全不可见,调整height、Layout.preferredHeight等属性无效。

解决方案

问题核心在于布局未正确设置填充规则,以下是修改后的QML代码,关键修改点已标注:

import QtQuick 6.0
import QtQuick.Controls.Basic 6.0
import QtQuick.Layouts 6.0

ApplicationWindow {
    title: "Portmod"
    width: 640
    height: 480
    visible: true

    header: TabBar {
        id: mainTabBar
        width: parent.width

        TabButton {
            text: "Manage"
            width: implicitWidth
        }

        TabButton {
            text: "Search"
            width: implicitWidth
        }
    }

    StackLayout {
        id: mainStackLayout
        currentIndex: mainTabBar.currentIndex
        anchors.fill: parent  // 关键:让StackLayout填满窗口内容区域

        ColumnLayout {
            id: manageTab
            Layout.fillWidth: true  // 关键:让ColumnLayout填充StackLayout的宽度
            Layout.fillHeight: true  // 关键:让ColumnLayout填充StackLayout的高度

            RowLayout {
                Layout.fillWidth: true  // 关键:让RowLayout占满宽度

                TextField {
                    placeholderText: "Filter packages..."
                    Layout.fillWidth: true  // 关键:让TextField拉伸填满剩余空间
                }

                Button {
                    text: "Filter"
                }
            }

            HorizontalHeaderView {
                id: installedPackagesHeader
                syncView: installedPackagesTable
                Layout.fillWidth: true  // 关键:让表头占满窗口宽度
            }

            TableView {
                id: installedPackagesTable
                columnSpacing: 1
                rowSpacing: 1
                clip: true
                Layout.fillWidth: true  // 关键:让TableView占满宽度
                Layout.fillHeight: true  // 关键:让TableView拉伸至窗口底部

                model: installedPackagesModel

                Keys.onUpPressed: installedPackagesTableVerticalScrollBar.decrease()
                Keys.onDownPressed: installedPackagesTableVerticalScrollBar.increase()
                Keys.onLeftPressed: installedPackagesTableHorizontalScrollBar.decrease()
                Keys.onRightPressed: installedPackagesTableHorizontalScrollBar.increase()

                ScrollBar.vertical: ScrollBar {
                    id: installedPackagesTableVerticalScrollBar
                    parent: installedPackagesTable
                }

                ScrollBar.horizontal: ScrollBar {
                    id: installedPackagesTableHorizontalScrollBar
                    parent: installedPackagesTable
                }

                delegate: Rectangle {
                    implicitWidth: 300
                    implicitHeight: 25

                    Text {
                        text: display
                        anchors.left: parent.left
                    }
                }
            }
        }

        Rectangle {
            id: searchTab
            anchors.fill: parent  // 让搜索页填满窗口
        }
    }
}

修改说明

  1. StackLayout:添加anchors.fill: parent,确保它填满ApplicationWindow除顶部TabBar外的所有区域。
  2. ColumnLayout:设置Layout.fillWidth: true和Layout.fillHeight: true,让它完全填充StackLayout的空间,子元素才能合理分配高度。
  3. RowLayout:设置Layout.fillWidth: true,让顶部的搜索栏占满窗口宽度;TextField添加Layout.fillWidth: true,自动拉伸填满按钮外的剩余空间。
  4. HorizontalHeaderView:添加Layout.fillWidth: true,保证表头与窗口宽度一致。
  5. TableView:同时设置Layout.fillWidth: true和Layout.fillHeight: true,让它填充ColumnLayout的剩余空间,自然延伸至窗口底部。

模型代码(无需修改)

from PySide6.QtCore import QSortFilterProxyModel, QAbstractItemModel, QModelIndex, Qt

class InstalledPackagesProxyModel(QSortFilterProxyModel):
    def __init__(self, data: list[list]) -> None:
        super().__init__()

        self.realModel = InstalledPackagesModel(data)
        self.setSourceModel(self.realModel)

    def get_atom(self, index: QModelIndex) -> Atom:
        """
        Returns a reference to the source index instead of proxy index, to handle the sorted view.
        """
        mapped_index = self.mapToSource(index)
        data = [tuple(pkg_data_list) for pkg_data_list in self.realModel._data]
        return Atom(f"{data[mapped_index.row()][2]}/{data[mapped_index.row()][0]}")


class InstalledPackagesModel(QAbstractTableModel):
    def __init__(self, data: list[list]):
        super(InstalledPackagesModel, self).__init__()
        self._data = data
        self.header_labels = ["Name", "Use Flags", "Category", "Version"]

    def data(self, index, role):
        if role == Qt.DisplayRole:  # type: ignore
            value = self._data[index.row()][index.column()]

            if isinstance(value, Atom):
                return str(value)

            return value

    def rowCount(self, index):
        return len(self._data)

    def columnCount(self, index):
        try:
            return len(self._data[0])
        # If there are no installed mods in the prefix
        except IndexError:
            return 1

    def headerData(self, section, orientation, role=Qt.DisplayRole):  # type: ignore
        if role == Qt.DisplayRole and orientation == Qt.Horizontal:  # type: ignore
            return self.header_labels[section]
        return QAbstractTableModel.headerData(self, section, orientation, role)

内容的提问来源于stack exchange,提问作者PopeRigby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:40:43