admin管理员组

文章数量:1418619

I have a TableView below two HorizontalHeaderViews--one to display the header, and one to implement filtering--and the text inside the TextInput of the "filter" HorizontalHeaderView moves to a different delegate's TextInput when forceLayout() is called.

Here is my code (with sensitive naming and aesthetic information removed):

Frame {
    id: listFrame
    
    property var filterDictionary: ({})

    signal focusNextField(currentField: int)
    signal focusPrevField(currentField: int)

    anchors.top: buttonRow.bottom
    anchors.bottom: chartFrame.top
    anchors.left: parent.left
    anchors.right: parent.right
    clip: true

    HorizontalHeaderView {
        id: horizontalHeader
        anchors.left: tableView.left
        anchors.top: parent.top
        syncView: tableView
        clip: true

        delegate: Rectangle {
            implicitHeight: 25
            implicitWidth: 100

            Text {
                id: headerNameDelegate
                anchors.fill: parent
                anchors.centerIn: parent
                text: model.display

                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignHLeft

                font.bold: true
            }
        }
    }

    HorizontalHeaderView {
        id: filterHeader
        anchors.left: tableView.left
        anchors.top: horizontalHeader.bottom
        syncView: tableView
        clip: true

        delegate: Rectangle {
            id: columnDelegate
            implicitHeight: 25
            implicitWidth: 100
            
            TextInput {
                id: textInputDelegate
                anchors.fill: parent

                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignHLeft

                onTextEdited: function() {
                    if (text != "") {
                        filterDictionary[display] = text
                    }
                    else {
                        delete filterDictionary[display]
                    }
                }

                onAccepted: function() {
                    backend.query_db_with_filter(JSON.stringify(filterDictionary))
                    selected_row = -1
                    tableView.forceLayout()
                }

                Keys.onTabPressed: function() {
                    root.focusNextField(column)
                }

                Keys.onBacktabPressed: function() {
                    root.focusPrevField(column)
                }

                function onFocusNextField(field) {
                    try {
                        if (column == field + 1) {
                            textInputDelegate.forceActiveFocus()
                        }
                    }
                    catch (err) {}
                }

                function onFocusPrevField(field) {
                    try {
                        if (column == field - 1) {
                            textInputDelegate.forceActiveFocus()
                        }
                    }
                    catch (err) {}
                }

                Component.onCompleted: {
                    root.focusNextField.connect(onFocusNextField)
                    root.focusPrevField.connect(onFocusPrevField)
                }
            }
        }
    }

    TableView {
        id: tableView
        anchors.top: filterHeader.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        alternatingRows: true
        clip: true

        model: backend.view_data.list_data

        delegate: Rectangle {
            id: cellRect
            clip: true

            property alias cellTextAlias: cellText

            Text {
                id: cellText
                text: display
                anchors.verticalCenter: parent.verticalCenter
                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignHLeft

                HoverHandler {
                    id: cellTextMouseArea
                    acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
                    cursorShape: Qt.PointingHandCursor
                }
            }
        }

        TapHandler {
            id: tapHandler
            gesturePolicy: TapHandler.ReleaseWithinBounds
            onTapped: function(eventPoint, button) {
                var cell = tableView.cellAtPosition(eventPoint.position, true)
                var snCellIndex = tableView.index(cell.y, 0)
                var snCell = tableView.cellAtIndex(snCellIndex)
                var sn = tableView.itemAtCell(snCell).cellTextAlias.text
                selected_row = cell.y
                backend.update_graph(sn)
            }

            onDoubleTapped: function(eventPoint, button) {
                loadSelectedData()
            }
        }
        
        function loadSelectedCart() {
            var snCellIndex = tableView.index(selected_row, 0)
            var snCell = tableView.cellAtIndex(snCellIndex)
            var sn = tableView.itemAtCell(snCell).cellTextAlias.text
            backend.populate_data(sn)
            selected_row = -1
            closeTable()
        }
    }
}

The text doesn't always move to the same column, so I don't think it's an issue with my signals and slots for changing the active focus for a delegate (unless the column of the delegate of filterHeader changes).

I'm aware of the existence of QSortFilterProxyModel and that I could do sorting and filtering that way, but since I'm getting my data from a database (and I don't want to hold onto thousands of rows of data just so I can filter a few dozen rows out of it) it made more sense to filter this way.

Does anyone know what's going on here?

本文标签: