From 98d73eb6cb3930ac95b7e966124b82aff3164ec4 Mon Sep 17 00:00:00 2001 From: zhuzichu Date: Tue, 20 Jun 2023 18:32:10 +0800 Subject: [PATCH] update --- example/CMakeLists.txt | 2 +- example/qml/component/CodeExpander.qml | 3 +- example/qml/global/ItemsOriginal.qml | 4 +- example/qml/page/T_Pagination.qml | 49 +++ example/qml/page/T_TableView.qml | 215 +++------- src/CMakeLists.txt | 2 +- .../FluentUI/Controls/FluPagination.qml | 3 +- .../FluentUI/Controls/FluTableView.qml | 388 ++++++------------ .../FluentUI/Controls/FluTableView2.qml | 164 -------- 9 files changed, 245 insertions(+), 585 deletions(-) create mode 100644 example/qml/page/T_Pagination.qml delete mode 100644 src/imports/FluentUI/Controls/FluTableView2.qml diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 67837152..f0c480e4 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -20,7 +20,7 @@ endif() file(TO_CMAKE_PATH "/" PATH_SEPARATOR) #设置版本号 -add_definitions(-DVERSION=1,3,5,1) +add_definitions(-DVERSION=1,3,6) find_package(Qt6 REQUIRED COMPONENTS Quick) qt_standard_project_setup() diff --git a/example/qml/component/CodeExpander.qml b/example/qml/component/CodeExpander.qml index 680f8f5f..55ec9ed8 100644 --- a/example/qml/component/CodeExpander.qml +++ b/example/qml/component/CodeExpander.qml @@ -131,7 +131,8 @@ FluExpander{ "FluCopyableText", "FluAcrylic", "FluRemoteLoader", - "FluMenuBar" + "FluMenuBar", + "FluPagination" ]; code = code.replace(/\n/g, "
"); code = code.replace(/ /g, " "); diff --git a/example/qml/global/ItemsOriginal.qml b/example/qml/global/ItemsOriginal.qml index 004bfb63..b65ad888 100644 --- a/example/qml/global/ItemsOriginal.qml +++ b/example/qml/global/ItemsOriginal.qml @@ -259,9 +259,9 @@ FluObject{ } } FluPaneItem{ - title:"TableView2" + title:"Pagination" onTap:{ - navigationView.push("qrc:/example/qml/page/T_TableView2.qml") + navigationView.push("qrc:/example/qml/page/T_Pagination.qml") } } FluPaneItem{ diff --git a/example/qml/page/T_Pagination.qml b/example/qml/page/T_Pagination.qml new file mode 100644 index 00000000..fa072dc6 --- /dev/null +++ b/example/qml/page/T_Pagination.qml @@ -0,0 +1,49 @@ +import QtQuick +import QtQuick.Layouts +import QtQuick.Window +import QtQuick.Controls +import "qrc:///example/qml/component" +import FluentUI + +FluScrollablePage{ + + title:"Pagination" + + FluArea{ + Layout.fillWidth: true + height: 200 + paddings: 10 + Layout.topMargin: 20 + ColumnLayout{ + spacing: 20 + anchors.verticalCenter: parent.verticalCenter + FluPagination{ + pageCurrent: 1 + pageButtonCount: 5 + itemCount: 5000 + } + FluPagination{ + pageCurrent: 2 + itemCount: 5000 + pageButtonCount: 7 + } + FluPagination{ + pageCurrent: 3 + itemCount: 5000 + pageButtonCount: 9 + } + } + + } + CodeExpander{ + Layout.fillWidth: true + Layout.topMargin: -1 + code:'FluPagination{ + pageCurrent: 1 + itemCount: 1000 + pageButtonCount: 9 +}' + } + + +} diff --git a/example/qml/page/T_TableView.qml b/example/qml/page/T_TableView.qml index 7eacfa01..2f61a769 100644 --- a/example/qml/page/T_TableView.qml +++ b/example/qml/page/T_TableView.qml @@ -5,162 +5,12 @@ import QtQuick.Window import FluentUI import "qrc:///example/qml/component" -FluScrollablePage{ +FluContentPage{ title:"TableView" Component.onCompleted: { - const columns = [ - { - title: '姓名', - dataIndex: 'name', - width:100, - - }, - { - title: '年龄', - dataIndex: 'item_age', - width:100, - minimumWidth:100 - }, - { - title: '住址', - dataIndex: 'address', - width:200 - }, - { - title: '别名', - dataIndex: 'nickname', - width:100 - }, - { - title: '操作', - dataIndex: 'action', - width:120 - }, - ]; - table_view.columns = columns - loadData(1,10) - } - - Component{ - id:com_age - Item{ - id:item_age - property var ageArr: [100,300,500,1000] - height: 60 - FluComboBox{ - width: 80 - anchors{ - verticalCenter: parent.verticalCenter - left: parent.left - leftMargin: 10 - } - model: ListModel { - ListElement { text: 100 } - ListElement { text: 300 } - ListElement { text: 500 } - ListElement { text: 1000 } - } - Component.onCompleted: { - currentIndex=ageArr.findIndex((element) => element === dataModel.age) - } - } - } - } - - Component{ - id:com_action - Item{ - height: 60 - Row{ - anchors.centerIn: parent - spacing: 10 - FluFilledButton{ - text:"编辑" - horizontalPadding: 6 - onClicked:{ - showError(JSON.stringify(dataObject)) - } - } - FluFilledButton{ - text:"删除" - horizontalPadding: 6 - onClicked:{ - tableView.remove(dataModel.index) - } - } - } - } - } - - FluText{ - Layout.topMargin: 20 - text:"此TableView适用于小数据量,带分页的表格,大数据量请使用TableView2。" - } - - FluTableView{ - id:table_view - Layout.fillWidth: true - Layout.topMargin: 20 - pageCurrent:1 - pageCount:10 - itemCount: 1000 - onRequestPage: - (page,count)=> { - loadData(page,count) - } - } - - CodeExpander{ - Layout.fillWidth: true - Layout.topMargin: 10 - code:'FluTableView{ - id:table_view - Layout.fillWidth: true - Layout.topMargin: 20 - pageCurrent:1 - pageCount:10 - itemCount: 1000 - onRequestPage: - (page,count)=> { - loadData(page,count) - } - Component.onCompleted: { - const columns = [ - { - title: "姓名", - dataIndex: "name", - width:100 - }, - { - title: "年龄", - dataIndex: "age", - width:100 - }, - { - title: "住址", - dataIndex: "address", - width:200 - }, - { - title: "别名", - dataIndex: "nickname", - width:100 - } - ]; - table_view.columns = columns - const dataSource = [ - { - name: "孙悟空”, - age: 500, - address:"钟灵毓秀的花果山,如神仙仙境的水帘洞", - nickname:"齐天大圣" - } - ]; - table_view.dataSource = columns - } -}' + loadData(1,2000) } function loadData(page,count){ @@ -188,13 +38,68 @@ FluScrollablePage{ for(var i=0;i element === Number(display)) + selectAll() + } + TableView.onCommit: { + display = editText + } + } + } + + FluTableView{ + id:table_view + anchors.fill: parent + anchors.topMargin: 20 + columnSource:[ + { + title: '姓名', + dataIndex: 'name', + width:100, + minimumWidth:50 + + }, + { + title: '年龄', + dataIndex: 'age', + editDelegate:com_combobox, + width:100, + minimumWidth:100, + maximumWidth: 100 + }, + { + title: '住址', + dataIndex: 'address', + width:200 + }, + { + title: '别名', + dataIndex: 'nickname', + width:100, + + } + ] + } } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 90f8c372..06bbc421 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,7 +13,7 @@ endif() set(QML_PLUGIN_DIRECTORY ${CMAKE_PREFIX_PATH}/qml/FluentUI) #设置版本号 -add_definitions(-DVERSION=1,3,5,1) +add_definitions(-DVERSION=1,3,6) find_package(Qt6 REQUIRED COMPONENTS Core Quick Qml) qt_standard_project_setup() diff --git a/src/imports/FluentUI/Controls/FluPagination.qml b/src/imports/FluentUI/Controls/FluPagination.qml index 41fd1353..188b0932 100644 --- a/src/imports/FluentUI/Controls/FluPagination.qml +++ b/src/imports/FluentUI/Controls/FluPagination.qml @@ -9,9 +9,9 @@ Item { property string nextText: "下一页>" property int pageCurrent: 0 property int itemCount: 0 + property int pageButtonCount: 5 property int pageCount: itemCount>0?Math.ceil(itemCount/__itemPerPage):0 property int __itemPerPage: 10 - property int pageButtonCount: 5 property int __pageButtonHalf: Math.floor(pageButtonCount/2)+1 id: control implicitHeight: 40 @@ -34,7 +34,6 @@ Item { FluToggleButton{ property int pageNumber:1 visible: control.pageCount>0 - enabled: control.pageCurrent>1 checked: pageNumber === control.pageCurrent text:String(pageNumber) clickListener:function() { diff --git a/src/imports/FluentUI/Controls/FluTableView.qml b/src/imports/FluentUI/Controls/FluTableView.qml index a00c99d4..46b16cad 100644 --- a/src/imports/FluentUI/Controls/FluTableView.qml +++ b/src/imports/FluentUI/Controls/FluTableView.qml @@ -2,293 +2,163 @@ import QtQuick import QtQuick.Controls import QtQuick.Controls.Basic import QtQuick.Layouts +import Qt.labs.qmlmodels import FluentUI -Item { - property var columns : [] - property var dataSource : [] - property int pageCurrent: 1 - property int itemCount: 1000 - property int pageCount: 10 - property int itemHeight: 56 - property bool pageVisible: true - signal requestPage(int page,int count) +Rectangle { + property var columnSource + property var dataSource id:control - implicitHeight: layout_table.height - QtObject{ - id:d - property int columnsWidth: layout_table.headerItem.columnsWidth() - } - MouseArea{ - anchors.fill: parent - preventStealing: true - } - ListModel{ - id:model_columns - } - ListModel{ - id:model_data_source - } - onColumnsChanged: { - model_columns.clear() - model_columns.append(columns) + color: FluTheme.dark ? Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1) + onColumnSourceChanged: { + if(columnSource.length!==0){ + var com_column = Qt.createComponent("FluTableModelColumn.qml") + if (com_column.status === Component.Ready) { + var columns= [] + columnSource.forEach(function(item){ + var column = com_column.createObject(table_model,{display:item.dataIndex}); + columns.push(column) + }) + table_model.columns = columns + } + } } onDataSourceChanged: { - model_data_source.clear() - model_data_source.append(dataSource) + table_model.clear() + dataSource.forEach(function(item){ + table_model.appendRow(item) + }) + } + TableModel { + id:table_model } Component{ - id:header_columns - FluRectangle{ - id:layout_columns - height: control.itemHeight - width: parent.width - color:FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(247/255,247/255,247/255,1) - radius: [5,5,0,0] - function columnsWidth(){ - var w = 0 - for(var i=0;i{ - clickPos = Qt.point(mouse.x, mouse.y) - } - preventStealing: true - onPositionChanged: - (mouse)=>{ - var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y) - var minimumWidth = item_column_text.implicitWidth+28 - if(model.minimumWidth){ - minimumWidth = model.minimumWidth - } - item_column.width = Math.max(item_column.width+delta.x,minimumWidth) - } - } - } - } + id:com_edit + FluTextBox { + anchors.fill: parent + text: display + verticalAlignment: TextInput.AlignVCenter + Component.onCompleted: selectAll() + TableView.onCommit: { + display = text } } } - Flickable{ - id:layout_flickable - height: layout_table.height - anchors{ - top: parent.top - left: parent.left - right: parent.right - } - contentWidth: layout_table.width - clip:true - ScrollBar.horizontal: FluScrollBar { - } - Rectangle{ - anchors.fill: layout_table - radius: 5 - color: FluTheme.dark ? Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1) - } - ListView{ - id:layout_table - height: contentHeight - width: Math.max(layout_flickable.width,d.columnsWidth) - clip:true - interactive: false - removeDisplaced: Transition { - NumberAnimation { properties: "x,y"; duration: 167 } + ScrollView{ + id:scroll_table + anchors.left: header_vertical.right + anchors.top: header_horizontal.bottom + anchors.right: parent.right + anchors.bottom: parent.bottom + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + ScrollBar.vertical.policy: ScrollBar.AlwaysOff + TableView { + id:table_view + ListModel{ + id:model_columns } - header: header_columns - footer: Item{ - height: pageVisible ? 54 : 0 - clip: true - width: layout_table.width - FluPagination{ - id:pagination - height: 40 - pageCurrent: control.pageCurrent - onPageCurrentChanged: control.pageCurrent = pageCurrent - itemCount: control.itemCount - pageCount: control.pageCount - onRequestPage: - (page,count)=> { - control.requestPage(page,count) - } - anchors{ - top: parent.top - right: parent.right + boundsBehavior: Flickable.StopAtBounds + ScrollBar.horizontal: FluScrollBar{} + ScrollBar.vertical: FluScrollBar{} + selectionModel: ItemSelectionModel {} + columnWidthProvider: function(column) { + let w = explicitColumnWidth(column) + if (w >= 0){ + var minimumWidth = columnSource[column].minimumWidth + var maximumWidth = columnSource[column].maximumWidth + if(!minimumWidth){ + minimumWidth = 100 } - Connections{ - target: control - function onPageCurrentChanged(){ - if (control.pageCurrent!==pagination.pageCurrent) - { - pagination.calcNewPage(control.pageCurrent) - } - } + if(!maximumWidth){ + maximumWidth = 65535 } + + return Math.min(Math.max(minimumWidth, w),maximumWidth) } + return implicitColumnWidth(column) } - model:model_data_source - delegate: Control{ - id:item_control - height: maxHeight() - width: layout_table.width - property var model_values : getObjectValues(index) - property var itemObject: getObject(index) - property var listModel: model - Rectangle{ + rowHeightProvider: function(row) { + let h = explicitRowHeight(row) + if (h >= 0){ + return Math.max(40, h) + } + return implicitRowHeight(row) + } + model: table_model + clip: true + delegate: Rectangle { + required property bool selected + required property bool current + color: selected ? FluTheme.primaryColor.lightest: (row%2!==0) ? control.color : (FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06)) + implicitHeight: 40 + implicitWidth: columnSource[column].width + FluText { + text: display anchors.fill: parent - color: { - if(item_control.hovered){ - return FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1) - } - return FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(1,1,1,1) - } + anchors.margins: 10 + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter } - FluDivider{ - id:item_divider - width: parent.width - height: 1 - anchors.right: parent.right - anchors.bottom: parent.bottom - } - Row{ - id: table_row - spacing: 0 - anchors.fill: parent - Repeater{ - id:repeater_rows - model: model_values - delegate:FluControl{ - id:item_row_control - width: layout_table.headerItem.widthByColumnIndex(index) - height: item_control.height - focusPolicy:Qt.TabFocus - background: Item{ - FluFocusRectangle{ - visible: item_row_control.activeFocus - radius:8 - } - } - Loader{ - id:item_column_loader - property var model : modelData - property var dataModel : listModel - property var dataObject : itemObject - property var tableView : control - anchors.verticalCenter: parent.verticalCenter - width: parent.width - sourceComponent: { - if(model.itemData instanceof Component){ - return model.itemData - } - return com_text - } - } - function columnHeight(){ - return item_column_loader.item.height - } - } + TableView.editDelegate: { + var obj =columnSource[column].editDelegate + if(obj){ + return obj } - } - function maxHeight(){ - var h = 0 - for(var i=0;i= 0){ - var minimumWidth = columnSource[column].minimumWidth - var maximumWidth = columnSource[column].maximumWidth - if(!minimumWidth){ - minimumWidth = 100 - } - if(!maximumWidth){ - maximumWidth = 65535 - } - - return Math.min(Math.max(minimumWidth, w),maximumWidth) - } - return implicitColumnWidth(column) - } - rowHeightProvider: function(row) { - let h = explicitRowHeight(row) - if (h >= 0){ - return Math.max(40, h) - } - return implicitRowHeight(row) - } - model: table_model - clip: true - delegate: Rectangle { - required property bool selected - required property bool current - color: selected ? FluTheme.primaryColor.lightest: (row%2!==0) ? control.color : (FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06)) - implicitHeight: 40 - implicitWidth: columnSource[column].width - FluText { - text: display - anchors.fill: parent - anchors.margins: 10 - elide: Text.ElideRight - verticalAlignment: Text.AlignVCenter - } - TableView.editDelegate: { - var obj =columnSource[column].editDelegate - if(obj){ - return obj - } - return com_edit - } - } - } - } - Component{ - id:com_handle - FluControl { - width: 24 - height: 24 - background: Rectangle{ - radius: 12 - color: FluTheme.dark ? Qt.rgba(69/255,69/255,69/255,1) :Qt.rgba(1,1,1,1) - } - visible: SelectionRectangle.control.active - FluShadow{ - radius: 12 - } - Rectangle{ - width: 24 - height: 24 - radius: 12 - scale: pressed?4/10:hovered?6/10:5/10 - color:FluTheme.dark ? FluTheme.primaryColor.lighter :FluTheme.primaryColor.dark - anchors.centerIn: parent - Behavior on scale { - NumberAnimation{ - duration: 167 - } - } - } - } - } - SelectionRectangle { - target: table_view - bottomRightHandle:com_handle - topLeftHandle: com_handle - } - FluHorizontalHeaderView { - id: header_horizontal - textRole: "title" - model: columnSource - anchors.left: scroll_table.left - anchors.top: parent.top - syncView: table_view - boundsBehavior: Flickable.StopAtBounds - clip: true - } - FluVerticalHeaderView { - id: header_vertical - boundsBehavior: Flickable.StopAtBounds - anchors.top: scroll_table.top - anchors.left: parent.left - syncView: table_view - clip: true - } -} -