QML中的tablview嵌入checkbox问题。



  • QML中tablview怎么实现选中某一行使第一列的CheckBox选中?全选怎么实现?怎么遍历出已选择的行号?



  • @我叫胡孟岳 可以找到currentIndex,然后让ListModel::get获取元素,然后设置checkbox的cheked为true。全选的话,加上for循环。遍历的话,选择行号的时候保存一下,下次遍历就方便了。也可以实现undo等功能。



  • 你说的我不是很明白,代码贴给你帮我看看吧,谢谢。

    TableView{
        id: tableView
        anchors{top: proProListTopImage.bottom; left: parent.left; right: parent.right; bottom: parent.bottom}
        backgroundVisible: false                        //背景不可见
        alternatingRowColors: false
        frameVisible:false
        model: modelProList
        verticalScrollBarPolicy: Qt.ScrollBarAlwaysOff
        horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
    
    
    
        TableViewColumn
        {
            id: checkedColumn
            role: "checked"
            title: qsTr("选择");
            width: tableView.width * 0.2;
        }
    
        TableViewColumn{
            role: "name";
            title: qsTr("工厂编码");
            width: tableView.width * 0.4;
        }
    
        TableViewColumn{
            role: "value";
            title: qsTr("工厂名称");
            width: tableView.width * 0.4;
    
        }
    
        headerDelegate: Rectangle{
            color: "#414549"
            height: inventorypage.width * (60.0 / 640.0);
            Text{
                anchors.centerIn: parent
                text: styleData.value
                color: "white"
                font.pixelSize:  inventorypage.width * (45.0 / 640.0) * 0.7;
            }
        }
    
        itemDelegate: Item {
            CheckBox
            {
                id: checkbox;
                anchors.centerIn: parent
                visible: isCheckColumn( styleData.column );
                height: (93.0 / 640.0) * inventorypage.width;
                style: CheckBoxStyle {
                    indicator: Rectangle {
                        implicitWidth: inventorypage.width * (30.0 / 640.0);
                        implicitHeight: inventorypage.width * (30.0 / 640.0);
                        color:"#36393b";
                        radius: inventorypage.width * (15.0 / 640.0);
                        border.color:control.activeFocus ? "darkblue" : "lightblue";
                        border.width: 4;
    
                        Image{
                            id: checkStatus;
                            anchors.fill: parent;
                            visible: control.checked;
                            source: diffMonitorImagePath + "tick.png";
                        }
                    }
                }
            }
            Text
            {
                anchors{top: parent.top; topMargin: 0.3* height; right:parent.right}
                anchors{left: parent.left; leftMargin: 10}
                text: styleData.value;
                verticalAlignment: Text.AlignVCenter;
                horizontalAlignment: Text.AlignLeft;
                color: "white";
                anchors.centerIn: parent;
                height: (93.0 / 640.0) * inventorypage.width;
                font.pixelSize:  inventorypage.width * (32.0 / 640.0);
                elide: styleData.elideMode;
                wrapMode: Text.WrapAtWordBoundaryOrAnywhere;
            }
            MouseArea{
                id: mouseArgag
                anchors.fill: parent;
                onClicked: {
                    checkbox.checked = !checkbox.checked;
                }
            }
        }
    
        rowDelegate: Rectangle {
            id: rowRectdelete;
            height: (93.0 / 640.0) * inventorypage.width;
            color:"#36393b";
            Rectangle{
                height: 1;
                width: parent.width;
                anchors.bottom: parent.bottom;
                color: "#6a6a6a";
            }
        }
    }
    function isCheckColumn( columnIndex )
    {
        return tableView.getColumn( columnIndex ) === checkedColumn
    }
    

    我想实现随便点击tablview的某一行,该行第一列的checkbox状态为选中。



  • @我叫胡孟岳 首先我说说 TableView 的原理吧。不然会吃亏的。

    TableView,ListView,GridView,PathView,这些 View 会对视图进行优化,也就是当可见项(数据展示项)在看不到的地方就会销毁,这也是 View 为何可以显示无限个的数据展示项(硬盘为上限,每个数据展示项不能太大,一次能显示的数据展示项个数在合理范围)。

    先看看如下代码:

    ListView {
        model: 1000000 // 这里表示有一百万个数据
        delegate: Text {text: index}    // 显示数据
    }
    

    你会发现,如果真的要渲染一百万个 Text,机身内存是吃不消的,所以在显示上会做优化,也就是看不到的数据展示项,就不创建,当数据展示项超出视图时,就会被销毁。

    在看看如下代码:

    ListView {
        model: 1000000 // 这里表示有一百万个数据
        delegate: CheckBox { }
    }
    

    这里显示了一百万个 CheckBox,每个 CheckBox 都可以保存自己的被选中的状态 checkable。但是就如上面所说的,数据展示项在超出可见范围就会被销毁。也就是数据展示项本身如果保存了数据,在销毁前没有保存的话,就会丢失。

    所以解决的办法也很简单,另外构建一个数据,安装顺序保存这些 CheckBox 的状态值。

    具体项目代码可以查看 ImageExplorer/ImageExplorerPage.qml 第 89 行,以及第 139 行 143 行。

    由于相册显示使用了 GridView,如果每个图片展示项(数据展示项)都放一个 CheckBox 那么,数据展示项超出视图时,就会被销毁。也就不能保存你选择了哪些图片。所以构建一个 ListModel 或者数组保存这些数据即可。



  • This post is deleted!

Log in to reply
 

最近的回复

  • 看了你的脚本,看来PowerShell是一种shell的方言,支持function和自定义的符号。和bash还不一样。
    我以前也写过Apple Script,看来大家都在shell语言上加上自己的特性啊。
    顺便了解到你们主要用Visual Studio开发Qt应用的。😁 😁

    read more
  • @wentaojia2014
    代码中的 {1} 是自动生成的,注意删掉

    read more
  • 脚本玩家路过一下😁
    我写了一段Powershell脚本,可以一键打开/关闭调试信息和代码优化。
    原理就是解析.sln文件(xml格式),找到关联的所有.vcproj文件(也是xml格式),并把其中的字段修改掉。

    看脚本

    # filename: DebugInfoSwitch.ps1 Add-Type -AssemblyName System.Xml.Linq # 获取绝对路径 function GetAbsolutePath { [OutputType([string])] param([string]$filePath) $aPath = Resolve-Path $filePath return Split-Path $aPath } # 解析sln文件,提取出project列表 function ParseSolution { [OutputType([string[]])] param([string]$solutionFile) $parttern = [regex]"^Project*" [string[]] $projs = @() Get-Content $solutionFile | Where-Object {$_ -match $parttern} | ForEach-Object { $items = $_.ToString().Split(',') if ($items[1].EndsWith("vcxproj`"")) { $projs += $items[1] } } return $projs } #Write-Host($debugGroup | Format-Table | Out-String ) function UpdateDebugInfo { param([System.Xml.Linq.XNamespace]$xNamespace,[System.Xml.Linq.XElement] $group, [bool]$isOpen) [System.Xml.Linq.XElement]$xClCompile = $group.Element($xNamespace + "ClCompile") [System.Xml.Linq.XElement]$xLink = $group.Element($xNamespace + "Link") [System.Xml.Linq.XElement]$format = $xClCompile.Element($xNamespace + "DebugInformationFormat") [System.Xml.Linq.XElement]$optimization = $xClCompile.Element($xNamespace + "Optimization") [System.Xml.Linq.XElement]$generate = $xLink.Element($xNamespace + "GenerateDebugInformation") if ($null -eq $format) { $format = [System.Xml.Linq.XElement]::new($xNamespace + "DebugInformationFormat") $xClCompile.Add($format) } if ($null -eq $optimization) { $optimization = [System.Xml.Linq.XElement]::new($xNamespace + "Optimization") $xClCompile.Add($optimization) } if ($null -eq $generate) { $generate = [System.Xml.Linq.XElement]::new($xNamespace + "GenerateDebugInformation") $xLink.Add($generate) } if ($isOpen) { $format.SetValue("ProgramDatabase"); $optimization.SetValue("Disabled"); $generate.SetValue("true"); } else { $format.SetValue("None"); $optimization.SetValue("MaxSpeed"); $generate.SetValue("false"); } } function SwitchDebugInfo { param([string]$projPath, [bool]$open, [bool]$isRelease) if (Test-Path($projPath)) { [System.Xml.Linq.XDocument]$xDoc = [System.Xml.Linq.XDocument]::Load($projPath) [System.Xml.Linq.XNamespace]$xNamespace = $xDoc.Root.GetDefaultNamespace(); [System.Xml.Linq.XElement]$group = $null $groups = $xDoc.Root.Elements($xNamespace + "ItemDefinitionGroup") foreach ($i in $groups) { if ($isRelease) { if ($i.Attribute("Condition").Value -match "^*Release*") { $group = $i; break; } } else { if ($i.Attribute("Condition").Value -match "^*Debug*") { $group = $i; break; } } } UpdateDebugInfo $xNamespace $group $open $xDoc.Save($projPath) } } #脚本入口函数 function Main { param([string]$sln, [bool]$open, [bool]$isRelease) Write-Host("sln file ", $sln) $slnPath= GetAbsolutePath $sln $projList = ParseSolution $sln $t = $projList.Split(' ') | ForEach-Object { $s = $_.ToString() if ($s) { $projPath=-Join($slnPath, '\', ($s.SubString(1, $s.Length - 2) )) SwitchDebugInfo $projPath $open $isRelease } } } function Usage { Write-Host ("Usage: DebugInfoSwitch.ps1 slnFilePath mode[D/d for Debug, R/r for Release] open[Y/y for open, N/n for close]") Write-Host ("Example for open Release mode debugInfo: DebugInfoSwitch.ps1 xxx.sln R y") Write-Host ("Example for close Debug mode debugInfo: DebugInfoSwitch.ps1 xxx.sln d N") } #检查参数 [string]$sln = "" [bool]$open = $true [bool]$isRelease = $false if ( $args.Count -ne 3) { Usage return } $sln = $args[0] if ($args[1] -eq "D" -or $args[1] -eq "d") { $isRelease = $false } elseif ($args[1] -eq "R" -or $args[1] -eq "r") { $isRelease = $true } else { Usage return } if ($args[2] -eq "Y" -or $args[2] -eq "y") { $open = $true } elseif ($args[2] -eq "N" -or $args[2] -eq "n") { $open = $false } else { Usage return } #调用主函数 Main $sln $open $isRelease

    用的时候,再写个bat脚本,调用这个ps1并传参数就行了。
    比如打开Release模式的调试信息、同时关掉优化开关

    @echo off powershell.exe -NoProfile -ExecutionPolicy Bypass -File DebugInfoSwitch.ps1 ./you/path/to.sln R N

    关闭调试信息、打开优化开关,则是传相反的参数

    @echo off powershell.exe -NoProfile -ExecutionPolicy Bypass -File DebugInfoSwitch.ps1 ./you/path/to.sln R Y

    read more
  • 我将USD在Linux中依赖的文件和脚本放在了我创建的QQ群里,我们的QQ群是“上海USD研究小组”。加入本小组,可以快速地在USD中上手解决编译问题,以及快速得到同行的响应。
    上海USD研究小组

    read more

关注我们

微博
QQ群