在 Qt Quick 中从 ListView 制作自定义 TableView 的规范方法

2024-03-14

制作桌子的最佳方法是什么ListView?

假设给定一个二维字符串数组并且delegate因为所有列都是Labels。仅使用 QML 时如何以及何时计算每列的最大项目宽度?各内容Label不是恒定的(即implicitWidth在生命周期中是可变的)。

发明的实际原因TableView事实是,这 1 步TreeView会保持。


关于在 QML 中创建表的问题似乎经常发布,但我还没有看到编译所有不同选项的答案。有很多方法可以实现您的要求。我希望在这个答案中提供一些替代方案。

TableView(5.12 及更高版本)

(更新于 16/07/2021)

Qt 5.12 包含一个新的 Qt Quick 项目,称为TableView,它经过了彻底的重新设计,对于具有任意数量的行或列的数据模型具有良好的性能。它解决了之前存在的性能问题TableView来自“快速控制 1”。

在创建此答案时 TableView 不存在,但我在此处的最新答案中提供了新 TableView 的使用示例:https://stackoverflow.com/a/68347396/5414907 https://stackoverflow.com/a/68347396/5414907

它为根据委托调整列宽提供了良好的内置支持implicitWidth,但它仅对视口中的行执行此操作,这意味着滚动可能会显示不适合列的数据,除非您强制forceLayout().

如果您使用的是 Qt 5.12,并且您知道表格需要水平滚动和垂直滚动(行和列的数量超出了视图的容纳范围),那么这似乎是首选解决方案。

Qt 在这里提供了新 TableView 与旧 TableView 的性能比较:http://blog.qt.io/blog/2018/12/20/tableview-performance/ http://blog.qt.io/blog/2018/12/20/tableview-performance/

以下是 Qt 5.11 及更早版本的替代方法的摘要,或者如果由于某种原因您不想使用 Qt 5.12TableView(也许这些替代方法之一更适合您的数据模型?)。

网格布局

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

ApplicationWindow {
    visible: true
    width: 640
    height: 480

    ListModel {
        id: listModel
        ListElement { name: 'item1'; code: "alpha"; language: "english" }
        ListElement { name: 'item2'; code: "beta"; language: "french" }
        ListElement { name: 'item3'; code: "long-code"; language: "long-language" }
    }

    GridLayout {
        flow: GridLayout.TopToBottom
        rows: listModel.count
        columnSpacing: 0
        rowSpacing: 0

        Repeater {
            model: listModel

            delegate: Label {
                Layout.fillHeight: true
                Layout.fillWidth: true
                Layout.preferredHeight: implicitHeight
                Layout.preferredWidth: implicitWidth
                background: Rectangle { border.color: "red" }
                text: name
            }
        }
        Repeater {
            model: listModel

            delegate: Label {
                Layout.fillHeight: true
                Layout.fillWidth: true
                Layout.preferredHeight: implicitHeight
                Layout.preferredWidth: implicitWidth
                background: Rectangle { border.color: "green" }
                text: code
            }
        }
        Repeater {
            model: listModel

            delegate: Label {
                Layout.fillHeight: true
                Layout.fillWidth: true
                Layout.preferredHeight: implicitHeight
                Layout.preferredWidth: implicitWidth
                background: Rectangle { border.color: "blue" }
                text: language
            }
        }
    }
}

垂直列表视图

创建具有垂直方向的表格ListView有其优点和缺点。 优点:

  • 可滚动
  • 动态创建可视区域之外的委托,这意味着加载速度更快
  • 易于创建固定宽度的列,其中文本被省略或换行

Cons:

  • 对于垂直滚动ListView(这通常是人们想要的),动态列宽很难实现......即列宽设置为完全适合列中的所有值

列宽必须使用该列内所有模型数据的循环来计算,这可能会很慢并且不是您想要经常执行的操作(例如,如果用户可以修改单元格内容并且您希望调整列大小)。

当模型分配给列宽时,可以通过仅计算一次列宽来实现合理的折衷ListView,并且混合了固定宽度和计算宽度的列。

警告:下面是一个example计算列宽以适合最长的文本。如果您有一个大型模型,您应该考虑废弃 Javascript 循环并采用固定宽度的列(或相对于视图大小的固定比例)。

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

ApplicationWindow {
    visible: true
    width: 640
    height: 480

    ListModel {
        id: listModel
        ListElement { name: 'item1'; code: "alpha"; language: "english" }
        ListElement { name: 'item2'; code: "beta"; language: "french" }
        ListElement { name: 'item3'; code: "long-code"; language: "long-language" }
    }

    ListView {
        property var columnWidths: ({"name": 100, "code": 50}) // fixed sizes or minimum sizes
        property var calculatedColumns: ["code", "language"]   // list auto sized columns in here

        orientation: Qt.Vertical
        anchors.fill: parent
        model: listModel

        TextMetrics {
            id: textMetrics
        }

        onModelChanged: {
            for (var i = 0; i < calculatedColumns.length; i++) {
                var role = calculatedColumns[i]
                if (!columnWidths[role]) columnWidths[role] = 0
                var modelWidth = columnWidths[role]
                for(var j = 0; j < model.count; j++){
                    textMetrics.text = model.get(j)[role]
                    modelWidth = Math.max(textMetrics.width, modelWidth)
                }
                columnWidths[role] = modelWidth
            }
        }

        delegate: RowLayout {

            property var columnWidths: ListView.view.columnWidths
            spacing: 0

            Label {
                Layout.fillHeight: true
                Layout.fillWidth: true
                Layout.preferredHeight: implicitHeight
                Layout.preferredWidth: columnWidths.name
                background: Rectangle { border.color: "red" }
                text: name
            }

            Label {
                Layout.fillHeight: true
                Layout.fillWidth: true
                Layout.preferredHeight: implicitHeight
                Layout.preferredWidth: columnWidths.code
                background: Rectangle { border.color: "green" }
                text: code
            }

            Label {
                Layout.fillHeight: true
                Layout.fillWidth: true
                Layout.preferredHeight: implicitHeight
                Layout.preferredWidth: columnWidths.language
                background: Rectangle { border.color: "blue" }
                text: language
            }
        }
    }
}

TableView(5.11 及更早版本)

(来自快速控制 1)

QC1 有一个TableView成分。 QC2 没有(在 Qt 5.9 中)。有一个正在开发中,但没有保证的时间表。

TableView由于性能问题一直不受欢迎,但它确实在 Quick Controls 1.0 到 1.4 之间得到了改进,并且仍然是一个可用的组件。 QC1 和 QC2 可以在同一应用中混合使用。

Pros

  • 轻松实现电子表格样式的用户可调整大小的列
  • 基于一个ListView,因此可以很好地处理大量行。
  • 唯一的内置组件类似于QTableView来自小部件

Cons

  • 默认样式是一种桌面灰色。与使用从头开始相比,您可能会花费更多时间尝试覆盖样式ListView.
  • 自动调整列大小以适应最长的内容不太实用/不起作用。

Example:

import QtQuick 2.7
import QtQuick.Controls 1.4 as QC1
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

ApplicationWindow {
    visible: true
    width: 400
    height: 200

    ListModel {
        id: listModel
        ListElement { name: 'item1'; code: "alpha"; language: "english" }
        ListElement { name: 'item2'; code: "beta"; language: "french" }
        ListElement { name: 'item3'; code: "long-code"; language: "long-language" }
    }

    QC1.TableView {
        id: tableView
        width: parent.width
        model: listModel

        QC1.TableViewColumn {
            id: nameColumn
            role: "name"
            title: "name"
            width: 100
        }
        QC1.TableViewColumn {
            id: codeColumn
            role: "code"
            title: "code"
            width: 100
        }
        QC1.TableViewColumn {
            id: languageColumn
            role: "language"
            title: "language"
            width: tableView.viewport.width - nameColumn.width - codeColumn.width
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Qt Quick 中从 ListView 制作自定义 TableView 的规范方法 的相关文章

  • 用 C++/Qt 编写的程序中的 RTF / doc / docx 文本提取

    我正在写一些程序Qt https en wikipedia org wiki Qt 28software 29 C 我需要从中读取文本微软Word https en wikipedia org wiki Microsoft Word RTF
  • 第一次信号发射后自动断开

    我正在从文件加载网页 然后替换其中的一些 html self template web page QtWebKit QWebPage self template web page mainFrame load QtCore QUrl tem
  • 如何让小部件在上下文菜单出现时接收鼠标释放事件

    在Ubuntu20 04上 当上下文菜单出现时 我无法让小部件接收鼠标释放事件 而Windows可以接收 我的pyqt版本是5 15 2 我考虑过手动发送鼠标释放事件 但我不知道当上下文菜单出现时哪些系统会收到鼠标释放事件 这样做可能会导致
  • 如何在QT上暂停和重新启动Qtimer

    我有 Ubuntu 我正在使用 IDEQT on C 我将暂停和恢复计时器 例如 void Ordonnancer les taches on pushButton clicked connect dataTimer SIGNAL time
  • 想知道如何在 ANDROID 可扩展列表中获取所选项目

    我有一个可扩展列表 其中包含组 大陆和子组 国家 单击一个国家 地区时 我希望该国家 地区显示在另一类的文本视图中 package com zeus eca import android app ExpandableListActivity
  • android listviews:页眉和页脚视图

    在我的 ListActivity 中 我需要页眉和页脚视图 位于列表的顶部和底部 分别用作列表上的上一页和下一页按钮 因为我只想一次仅显示 20 个项目 我通过执行以下操作来设置头视图和脚视图 getListView addHeaderVi
  • 完全彻底卸载QT Creator

    问题 如何从 Linux 机器上卸载 QT Creator 我的 Debian Jessie 机器上的安装已损坏 我尝试过重新安装 修复等 但没有成功 建议我完全卸载 获取最新版本并重新安装 问题是我不确定如何执行此操作 每次我尝试时 QT
  • 屏幕解锁时崩溃

    我的应用程序运行良好 除了当用户停止使用手机足够长的时间以至于屏幕锁定时 当他们解锁应用程序时 应用程序崩溃了 我有点不知道为什么 这是错误 这是惰性适配器 package com buhz helpers import java util
  • 使用 OpenGL 渲染 QImage

    与我相关的其他问题 https stackoverflow com questions 20126354 render qimage from sooffscreenrenderer in qglwidget 我认为更核心的问题是 如何渲染
  • 如何根据 ListActivity 中长按的项目设置特定的上下文菜单?

    我有一个列表活动 我选择手动添加第一个项目 即 添加新项目 我已经注册了整个列表视图的上下文菜单 使用registerForContextMenu getListView 直接进入onCreate 当建立上下文菜单时 系统调用onCreat
  • 在 Qt 中使用多个不同的流读取同一文件

    使用 Qt 是否可以使用多个流读取文件以同时访问其中的不同数据部分 请注意 Qt 中的流 QTextStream QDataStream 不处理底层设备中的位置 流类只是一个包装器 用于更轻松地解析设备 QFile 实例 内的二进制数据 因
  • didSelectRowAtIndexPath 与点击手势识别器冲突

    我通过情节提要在 ViewController 中设置了点击手势识别器 因此 如果显示此视图中的所有点击 将隐藏键盘 问题是 现在 我在这个视图中添加了一个 TableView 当我点击一个单元格时 使用点击手势识别器设置的方法是调用 而不
  • listview.setOnItemClickListener 和 row.setOnClickListener 的区别

    我正在创建一个自定义数组适配器 现在我想实现一个处理单击视图的函数 我心里有两个选择 但我想知道性能 工作速度或其他方面是否存在差异 选项 1 在 arrayAdapter 本身中 row setOnClickListener new On
  • 是否有 Qt 小部件可以浏览应用程序中小部件的层次结构(类似于 Spy++)?

    我们有一个具有复杂的小部件层次结构的应用程序 我希望能够以与 Spy 类似的方式浏览此层次结构 查看和编辑属性 例如大小 如果有一个小部件可以显示此信息 则它不需要在外部应用程序中运行 那么问题来了 这样的神兽存在吗 您可以使用Gammar
  • 第二次单击时 ListViewItem 出现 ArgumentOutOfRangeException

    当我第二次单击时 下面的方法给出了 ArgumentOutOfRangeException 错误 并表示索引 0 不是有效索引 第一次点击就可以了 ListView FullRowSelect 设置为 true 我发现按 ALT 和 CON
  • Qt中Q_PROPERTY的意义是什么?

    我无法理解 Q PROPERTY 的用法 Q PROPERTY 如何帮助程序具有防御性 它是干什么用的 我看过这个论坛 但确实无法应用 我已经理解了这个例子 但不明白它的用法 这是一个例子 我能从中得到什么 我知道阅读将赋予只读特权 wri
  • 将TableView数据显示到另一个窗口中包含JavaFx中的TextField

    我制作了两个 Fxml 文件 一个包含 TextField 另一个包含 TableView 它有它的 Controller 类 我想在执行鼠标单击操作事件时显示从 TableView 到 TextField 的数据 但我们没有得到结果 它显
  • Android - 如何在 ListView 的背景上显示垂直线(并根据行高)?

    如何在背景上显示一条垂直线 如下图蓝色突出显示的那条 在此示例中 我有一个带有 ImageView 元素的 ListView 和 TextView 但它与线条无关 并且我希望这些项目的背景上有一条垂直线 让人感觉它们与每个项目 连接 另请注
  • Qt(在 Windows 上)将权限级别设置为“requireAdministrator”

    我正在使用 Qt Creator 并努力制作 exe文件默认以管理员身份运行 在线阅读所有解决方案我试图将这一行放入我的 pro file QMAKE LFLAGS MANIFESTUAC level requireAdministrato
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap

随机推荐

  • 谷歌索引页面加载后通过ajax或javascript检索的文本

    几个谷歌问题 1 谷歌是否有机会 看到 使用ajax检索的文本 用户从一系列选择框中进行选择 然后显示数据库中的一些文本 2 如果我使用javascript更改页面标题 在HEAD区域之外 谷歌会索引修改后的标题吗 抱歉 如果这些是琐事问题
  • 如何快速隐藏/显示按钮

    我正在尝试使用 if 语句来使按钮在标签显示某种状态时隐藏 并在标签显示其他内容时出现 标签的名称是 Status 当它显示时 Closed 我希望它隐藏 当它显示时 Open 就会出现 var query3 PFQuery classNa
  • 在自定义 JSF 组件收到 AJAX 更新后调用自定义 JavaScript 代码

    我已经实现了自己的 JSF 组件及其渲染器 并且运行良好 目前 在更改组件树中的某些内容后 我开始重新加载 JavaScript 页面 现在我想在 AJAX 调用传递新数据后更新我的组件 这就像我在单击按钮后向表中插入新行 这会启动 AJA
  • PHP 通过类传递对象?

    重建整个类布局后 我在使用多个类实例时仍然遇到问题 class User public variable public function getUser this gt variable It works return bob class
  • Twilio 通话应用账单扣除

    我们正在制作三种方式调用 Android 应用程序 两个参与者是应用程序用户 第三个参与者是使用 TWILIO 的任何电话号码 我们已经实现了通话功能 我们的通话正在接通 但问题是 我们需要在服务器端知道谁是发起呼叫的用户 以便我们可以从该
  • 如何在本地服务器上安装CloudFoundry

    我知道 CF 是为在多个云服务上运行而设计的 以实现微服务应用程序的统一视图 但是 我想在我的 CentOS 本地服务器上安装并运行 Cloud Foundry 换句话说 我想在一台运行 CF 的服务器上设置我的私有 云 作为基于微服务的应
  • 如何在 tkinter 中滚动到 TreeView 的底部

    我在 Tkinter 中使用树视图模仿了一个表格小部件 并添加一个链接到它的滚动条 问题是因为我的数据是按分钟自动添加到底部的 并且我希望滚动始终滚动到底部 我知道 text see END 在文本小部件中完美工作 但就我而言 树视图小部件
  • Java NoSuchAlgorithmException - SunJSSE、sun.security.ssl.SSLContextImpl$DefaultSSLContext

    背景 我一直在它自己的 Eclipse 项目中使用 Authorize net SDK 一切都运转良好 然后我需要将其添加到我的主项目中 我将依赖项添加到类路径中 并将其复制到我需要的代码块中 它应该有效 Problem 长话短说 代码在我
  • 表单验证失败后重新填充 Codeigniter 中的复选框

    在表单验证不成功将用户返回到同一表单后 我在重新填充一组复选框时遇到问题 下拉菜单和文本输入可以重新填充 但复选框不能 这是复选框的代码片段 td Casual br Romantic br td
  • 如何获取 Xamarin.Forms 中嵌入文件的 URL/路径

    我无法访问 Xamarin Forms 项目中嵌入的 mp4 文件 根据Xamarin Forms 中的文件处理 https learn microsoft com en us xamarin xamarin forms app funda
  • SassError:找不到要导入的样式表。 @use '~@angular/material' 作为垫子;

    我使用 CLI 创建了一个 Angular 项目 我正在使用 SCSS 并且我将 Angular Material 包含在自定义主题 iirc 中 我添加了几个虚拟组件 应用程序仍然构建得很好 然后我需要使用 Angular Materia
  • Swift 3 类型“Any”没有下标成员

    我刚刚将我的项目转换为 Swift 3 我这里有这行代码 let type self data indexPath row Type as String 但现在我得到这个错误 Type Any has no subscript member
  • 不允许使用非成员函数重载 C++ 转换运算符的理由是什么

    C 0x 添加了显式转换运算符 但它们必须始终定义为 Source 类的成员 这同样适用于赋值运算符 它必须在 Target 类上定义 当所需转换的 Source 和 Target 类彼此独立时 Source 都不能定义转换运算符 Targ
  • 如何通过IP地址列出网络计算机上所有已安装的软件?

    我想知道如何获取网络计算机上安装的软件列表 我能够获取本地计算机上安装的软件列表 但不确定如何提取网络内计算机上已安装软件的详细信息 我使用服务器名称或网络计算机的 IP 地址作为唯一的输入 下面是从本地计算机获取已安装软件的详细信息的代码
  • 在 Swift 中比较 UIColors 时出现问题

    我需要比较两个 UIColor 但由于某种原因它总是返回 false 我尝试比较使用 and isEqual 但它们似乎都不起作用 This is a sample of the colors I have created let blue
  • Google 地图 + jQuery:渲染错误

    将 google 地图放入 jquery ui 选项卡中时 地图在某些情况下无法正确显示 重现 Go here http www fiveminuteargument com html map test html 单击 列表 链接 调整浏览
  • 使用 save() 玩框架 JPA 问题

    我试图在数据库中保存一个简单的对象 但这给我带来了问题 这是我的对象类 Entity Table name lines public class Line extends GenericModel Id Column name line i
  • 不允许子操作执行重定向操作。 (使用部分视图)

    我正在尝试使用数据库中的一些数据加载部分视图 但在运行应用程序时遇到以下问题 不允许子操作执行重定向操作 我不知道为什么会发生这种情况 因为我对 MVC 技术还很陌生 这是我的PartialViewResult控制器中的方法 public
  • 使用字符串插值内的变量指定小数位

    我有一个字符串格式 其中包含两个整数变量 每个变量都需要格式化为可变长度 int x 1234 int y 42 Simplified real values come from method outputs so must use the
  • 在 Qt Quick 中从 ListView 制作自定义 TableView 的规范方法

    制作桌子的最佳方法是什么ListView 假设给定一个二维字符串数组并且delegate因为所有列都是Labels 仅使用 QML 时如何以及何时计算每列的最大项目宽度 各内容Label不是恒定的 即implicitWidth在生命周期中是