ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

NodeGui 中的 QTableView 实战指南:用 JavaScript 构建原生桌面表格视图

NodeGui 中的 QTableView 实战指南:用 JavaScript 构建原生桌面表格视图 桌面应用跨平台【免费下载链接】nodeguiA library for building cross-platform native desktop applications with Node.js and CSS . React NodeGui : https://react.nodegui.org and Vue NodeGui: https://vue.nodegui.org项目地址https://gitcode.com/gh_mirrors/no/nodegui点击查看免费下载QTableView 是 NodeGui基于 Node.js Qt 的跨平台原生桌面应用框架提供的表格视图控件是 Qt 官方 QTableView 类的 JavaScript 封装负责以模型/视图Model/View架构呈现二维表格数据。本指南聚焦于如何在实际 NodeGui 应用中创建 QTableView、绑定数据模型、定制行列与网格外观、控制选择与排序行为并结合仓库源码解释其底层实现机制。认识 QTableViewNodeGui 中的模型/视图表格在 Qt 的模型/视图体系中QTableView提供了一个默认的模型/视图实现的表格视图官方文档原语The QTableView class provides a default model/view implementation of a table view。在 NodeGui 中它被包装成 TypeScript 类 QTableView作为 Qt QTableView 类的 JS 封装对外提供。它的核心定位是只负责显示与交互不负责存储数据。表格内容由独立的模型Model提供视图View通过模型索引QModelIndex读取数据并渲染。这种解耦使得同一个数据模型可以被多个视图复用也便于将数据与界面逻辑彻底分离。继承层次从文档的 Hierarchy 一节可以看到 QTableView 的完整继承链QAbstractItemView QAbstractScrollArea QFrame QWidget向上追溯 ↳ QTableView ↳ QTableWidgetQAbstractItemView所有基于模型/视图架构的条目视图的抽象基类QListView、QTreeView、QTableView 等均继承自它QAbstractScrollArea提供滚动条、视口viewport等滚动区域能力QFrame提供边框、矩形、阴影等外观能力。在仓库 C 侧这一层次同样成立NTableView同时继承QTableView与NodeWidget见 ntableview.hpp并通过宏QABSTRACTITEMVIEW_WRAPPED_METHODS_DECLARATION复用父类的全部导出方法见 qtableview_macro.h。类型参数与信号QTableView 是一个泛型类类型参数Signals默认取QTableViewSignals而QTableViewSignals QAbstractItemViewSignals见 QTableView.ts。C 侧通过QTABLEVIEW_SIGNALS宏同样继承自QABSTRACTITEMVIEW_SIGNALS意味着 QTableView 自身不新增信号而是完整复用父类信号集如点击、选择变化、双击等条目视图信号。快速上手最小可用示例文档给出的最小示例如下两行代码即可创建表格视图const { QTableView } require(nodegui/nodegui); const tableview new QTableView();构造函数三种用法从文档的 Constructors 一节以及 qtableview_wrap.cpp 的实现可以看出构造函数接受一个可选参数调用方式行为new QTableView()创建一个无父级的表格视图new QTableView(parentWidget)创建表格视图并指定父级 QWidgetnew QTableView(nativeElement)包装一个已存在的原生 C 实例内部使用C 构造逻辑对 0 个参数直接new NTableView()对 1 个参数则判断是外部原生实例IsExternal还是父级控件包装对象分别执行包装或带父级构造。若参数个数非法会抛出TypeError: NodeGui: QTableViewWrap: Wrong number of arguments to constructor。与数据模型配合的完整示例单独创建 QTableView 并不会显示任何内容——必须先通过setModel()绑定数据模型。仓库自带的官方示例 modelview_1_readonly.ts 演示了最典型的只读用法import { ItemDataRole, QAbstractTableModel, QModelIndex, QTableView, QVariant } from ..; function main(): void { const tableView new QTableView(); const model new MyModel(); tableView.setModel(model); tableView.show(); (global as any).win tableView; } class MyModel extends QAbstractTableModel { rowCount(parent new QModelIndex()): number { return 2; } columnCount(parent new QModelIndex()): number { return 2; } data(index: QModelIndex, role ItemDataRole.DisplayRole): QVariant { if (role ItemDataRole.DisplayRole) { return new QVariant(Row${index.row() 1}, Column${index.column() 1}); } return new QVariant(); } } main();要点说明自定义模型需继承QAbstractTableModel并至少实现rowCount()、columnCount()与data()data()根据ItemDataRole.DisplayRole返回QVariant作为单元格显示文本tableView.show()之后视图才会出现在窗口中将视图挂到(global as any).win是为了防止被 Node.js 垃圾回收这与 NodeGui 的 WrapperCache 机制相关参见 WrapperCache.ts。核心 API 详解QTableView 自身方法文档中 QTableView 的方法数量庞大但绝大多数是沿继承链继承而来的通用控件方法如show()、resize()、setStyleSheet()、addEventListener()等。真正属于 QTableView 自身的 API 集中在表格专属能力上在 QTableView.ts 中可以看到完整实现。下面按功能分组讲解。行列尺寸与坐标换算方法说明rowAt(y: number): number返回给定 y 坐标所在的行号columnAt(x: number): number返回给定 x 坐标所在的列号rowViewportPosition(row): number返回某行在视口内的 y 坐标columnViewportPosition(column): number返回某列在视口内的 x 坐标rowHeight(row): number返回指定行的高度columnWidth(column): number返回指定列的宽度setRowHeight(row, height)设置指定行的高度setColumnWidth(column, width)设置指定列的宽度resizeRowToContents(row)/resizeRowsToContents()按内容自适应行高resizeColumnToContents(column)/resizeColumnsToContents()按内容自适应列宽这些坐标换算类方法在实现上直接透传原生 Qt 调用。例如 C 宏中columnAt的实现是this-instance-columnAt(x)参数以Int32Value()取出、结果以Napi::Number::New返回见 qtableview_macro.h。resizeColumnsToContents()/resizeRowsToContents()分别一次调整所有列/行适合在数据加载完成后调用以获得紧凑布局。行列的显示与隐藏方法说明hideColumn(column)/showColumn(column)隐藏 / 显示指定列hideRow(row)/showRow(row)隐藏 / 显示指定行setColumnHidden(column, hide)以布尔值控制列是否隐藏setRowHidden(row, hide)以布尔值控制行是否隐藏isColumnHidden(column): boolean查询列隐藏状态isRowHidden(row): boolean查询行隐藏状态这几组方法互为对称hideColumn/showColumn是便捷插槽Public SlotssetColumnHidden(column, hide)则把是否隐藏作为显式参数便于与状态变量联动。单元格合并Span方法说明setSpan(row, column, rowSpanCount, columnSpanCount)将 (row, column) 起始的单元格跨越 rowSpanCount 行、columnSpanCount 列rowSpan(row, column): number查询指定单元格跨越的行数columnSpan(row, column): number查询指定单元格跨越的列数clearSpans()清除所有合并恢复默认布局// 将第 0 行第 0 列的单元格横向合并 2 列作为表头说明单元格 tableView.setSpan(0, 0, 1, 2);表头Header访问方法说明horizontalHeader(): QHeaderView获取水平表头列标题栏verticalHeader(): QHeaderView获取垂直表头行号栏返回类型均为 QHeaderView。在 C 侧horizontalHeader()/verticalHeader()通过WrapperCache::instance.getWrapper(env, header)将原生QHeaderView指针包装为 JS 对象返回见 qtableview_macro.h这保证了同一原生对象多次访问得到同一个 JS 包装实例。获取表头后可以进一步定制标题文本、拉伸模式等。选择与排序方法说明selectRow(row)/selectColumn(column)选中整行 / 整列sortByColumn(column, order)按指定列排序order取 SortOrderAscendingOrder/DescendingOrdersetSortingEnabled(enable)/isSortingEnabled()开关/查询点击表头排序功能setCornerButtonEnabled(enable)/isCornerButtonEnabled()开关/查询左上角全选按钮选择行为的高级配置setSelectionMode、setSelectionBehavior、clearSelection、selectAll等继承自QAbstractItemView在 QAbstractItemView.ts 中有完整实现可配合QItemSelectionModel使用。网格与外观方法说明setShowGrid(show)/showGrid(): boolean开关/查询网格线显示setGridStyle(style)/gridStyle(): PenStyle设置/查询网格线画笔样式取值来自 PenStyle 枚举如SolidLine、DashLine、NoPen等setWordWrap(on)/wordWrap(): boolean开关/查询单元格文本自动换行值得注意的实现细节这部分属性型方法并未全部走原生调用而是利用了 Qt 的属性Property系统。例如setShowGrid(show)→this.setProperty(showGrid, show)setGridStyle(style)→this.setProperty(gridStyle, style)setSortingEnabled(enable)→this.setProperty(sortingEnabled, enable)setCornerButtonEnabled(enable)→this.setProperty(cornerButtonEnabled, enable)setWordWrap(on)→this.setProperty(wordWrap, on)。对应的读取方法如showGrid()、gridStyle()、isSortingEnabled()则通过this.property(...)读取并转换成boolean/int见 QTableView.ts。这与rowAt、setSpan等直接透传原生方法的实现方式形成了两种不同模式是理解 NodeGui 包装风格的切入点。继承自父类的重要能力文档 Index 中列出的绝大多数方法来自父类链这里整理与表格使用最相关的一组来自 QAbstractItemView模型/视图核心setModel(model: QAbstractItemModel)/setRootIndex(index)绑定数据模型、设置根索引currentIndex(): QModelIndex、setCurrentIndex(index)当前项selectionModel(): QItemSelectionModel选择模型setSelectionMode(mode)/setSelectionBehavior(behavior)选择模式与行为SelectionMode、QAbstractItemViewSelectionBehavior枚举setAlternatingRowColors(enable)/alternatingRowColors()交替行背景色setDragEnabled(enable)、setDragDropMode(mode)、setDropIndicatorShown(enable)拖放能力setEditTriggers(triggers)/editTriggers()编辑触发方式setItemDelegate(delegate)/setItemDelegateForColumn(column, delegate)/setItemDelegateForRow(row, delegate)统一/按列/按行定制绘制与编辑代理scrollTo(index, hint)默认ScrollHint.EnsureVisible、scrollToTop()、scrollToBottom()滚动定位setIndexWidget(index, widget)/indexWidget(index)为特定索引挂载普通 WidgetopenPersistentEditor(index)/closePersistentEditor(index)/isPersistentEditorOpen(index)持久化编辑器keyboardSearch(search)键盘增量搜索setTabKeyNavigation(enable)/tabKeyNavigation()Tab 键导航。来自 QAbstractScrollArea滚动区域setHorizontalScrollBarPolicy(policy)/setVerticalScrollBarPolicy(policy)ScrollBarPolicysetViewport(widget)/viewport()、horizontalScrollBar()/verticalScrollBar()maximumViewportSize()。来自 QWidget / QFrame通用控件能力窗口生命周期show()、hide()、close()、setWindowTitle()、setWindowIcon()等布局尺寸resize()、setFixedSize()、setMinimumSize()、setMaximumSize()、setSizePolicy()等样式setStyleSheet(styleSheet, postprocess true)、setInlineStyle(style, postprocess true)边框来自 QFramesetFrameShape(type)、setFrameShadow(type)、setFrameStyle(style)、setLineWidth()、setMidLineWidth()等焦点与输入setFocusPolicy()、setFocus()、setMouseTracking()、setInputMethodHints()等。此外所有 NodeGui 控件都通过 EventWidget 支持事件监听// 信号Signal监听例如继承自 QAbstractItemView 的信号 tableView.addEventListener(clicked, (index: QModelIndex) { console.log(clicked row${index.row()} col${index.column()}); }); // 事件Event监听例如悬停事件 tableView.addEventListener(WidgetEventTypes.HoverEnter, () { console.log(hover enter); });addEventListener/removeEventListener支持两种重载以Signals接口中的信号名为键或以WidgetEventTypes事件类型为键详见 EventWidget.ts 与文档 EventWidget 条目。内存与生命周期注意点文档中_id()方法继承自 QObject返回一个标识底层 C 对象的唯一数字——它是 C 对象内存地址的哈希可用于配合setLogCreateQObject()/setLogDestroyQObject()调试内存问题。QTableView 在 C 侧使用QPointerQTableView持有实例见 qtableview_wrap.h析构时通过extrautils::safeDelete(this-instance)安全删除见 qtableview_wrap.cpp。在 JS 侧创建控件后若不再被引用会被垃圾回收因此长期存活的窗口/视图建议挂载在全局对象上如示例中的(global as any).win tableView。NodeGui 的 WrapperCache 会在创建包装时注册wrapperCache.registerWrapper(QTableViewWrap, QTableView)见 QTableView.ts用于维护原生对象与 JS 包装对象的对应关系。在 NodeGui 应用中使用 QTableView 的完整流程综合以上内容一个可运行的实战骨架如下import { QTableView, QAbstractTableModel, QModelIndex, QVariant, ItemDataRole } from nodegui/nodegui; class MyModel extends QAbstractTableModel { private dataRows [ [Alice, Engineer], [Bob, Designer], [Carol, Manager], ]; rowCount(parent: QModelIndex new QModelIndex()): number { return this.dataRows.length; } columnCount(parent: QModelIndex new QModelIndex()): number { return 2; } data(index: QModelIndex, role: number ItemDataRole.DisplayRole): QVariant { if (role ItemDataRole.DisplayRole) { return new QVariant(this.dataRows[index.row()][index.column()]); } return new QVariant(); } } const table new QTableView(); const model new MyModel(); table.setModel(model); table.setColumnWidth(0, 120); table.resizeColumnsToContents(); table.setShowGrid(true); table.setSortingEnabled(true); table.setAlternatingRowColors(true); table.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows); table.show(); (global as any).win table;应用时需注意若使用自定义排序模型需要重写sort()方法否则开启setSortingEnabled(true)后按表头点击只会走默认排序逻辑resizeColumnsToContents()在模型数据就绪后调用效果最佳具体引入路径以项目实际安装为准nodegui/nodegui或仓库内src/lib的相对导入本仓库还提供了多份可直接对照的 modelview 系列示例modelview_2_formatting.ts、modelview_3_changingmodel.ts、modelview_4_headers.ts、modelview_5_edit.ts、modelview_buddy.ts。小结QTableView 是 NodeGui 中实现表格场景的核心控件它继承自QAbstractItemView通过setModel()与自定义的QAbstractTableModel协作把数据展示、行列操作、网格样式、排序选择、拖放编辑等能力完整地带到 JavaScript 世界。无论是做数据管理工具、报表界面还是配置面板掌握 QTableView 自定义模型这一组合即可在 NodeGui 中原生渲染高性能表格。更多模型/视图细节可继续阅读仓库中的 QAbstractItemModel.ts、QAbstractTableModel.ts 与 QModelIndex.ts。赞分享桌面应用跨平台【免费下载链接】nodeguiA library for building cross-platform native desktop applications with Node.js and CSS . React NodeGui : https://react.nodegui.org and Vue NodeGui: https://vue.nodegui.org项目地址https://gitcode.com/gh_mirrors/no/nodegui点击查看免费下载相关推荐NodeGui QListWidgetItem 完全指南用 JavaScript/TypeScript 创建原生桌面列表项NodeGui QListWidgetItem 完全指南用 JavaScript/TypeScript 创建原生桌面列表项 导读 QListWidgetIte桌面应用跨平台NodeGui 桌面应用开发使用 QTableWidget 构建基于单元格的表格视图NodeGui 桌面应用开发使用 QTableWidget 构建基于单元格的表格视图 本篇指南以 NodeGui 官方 API 文档为骨架深入讲解 QTab桌面应用跨平台NodeGui QTableWidgetItem 完全指南用 JavaScript 构建表格单元格项NodeGui QTableWidgetItem 完全指南用 JavaScript 构建表格单元格项 本指南基于 NodeGui 官方 API 文档与仓库源码桌面应用跨平台上一篇Redis事务与Lua脚本编程保证数据一致性的高级技巧下一篇audiobox-aesthetics输出解析用jq一行命令提取CE/CU/PC/PQ分数的4种玩法创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表