tableview selection broken after dynamically populating context menu structure via createObject



  • My Application contains a QML tableview and a (right-click) context menu. With a statically defined (in the QML) menu structure all is working fine.
    Now ever since I began to fill the menu structure dynamically with the following function, the tableview no longer allows to select any cell by left-clicking. It is still possible to right-click to select a cell, but with the side effect of popping up the context menu. Also there are some "glictches" that allow a cell to be selected by left-clicking that occur sporadically after closing the context menu.

    I derived this code from a different example which I found on StackOverflow. Any ideas what is wrong with the particular piece of code?

    function funcSetMenuItems(menuItemNameList) {
        listViewContextMenu.clear()
        for (var menuItemIdx = 0; menuItemIdx < menuItemNameList.length; menuItemIdx++)
        {
            var menuItemName = menuItemNameList[menuItemIdx];
            var menuItemId = menuItemIdx;
            var component = Qt.createComponent("ListViewContextMenuItem.qml");
            var menuItem = component.createObject(listViewContextMenu, {"text": menuItemName, "thisMenuItemId": menuItemId});
            listViewContextMenu.insertItem(menuItemId, menuItem);
        }
    }
    

    By selectively commenting various parts, I was able to single out this line as "cause":

    var menuItem = component.createObject(listViewContextMenu, {"text": menuItemName, "thisMenuItemId": menuItemId});
    

    If this line is not present, the tableview will work normally. However, no entries in the menu are created either. duh.

    For completeness, this is the QML for the created menuitem, and the main QML

    ListViewContextMenuItem.qml

    import QtQuick 2.1
    import QtQuick.Controls 1.3
    
    MenuItem {
        property int thisMenuItemId: 0
        signal itemTriggered(int menuItemId)
        onTriggered: {
            itemTriggered(thisMenuItemId)
        }
    }
    

    Main.qml

    import QtQuick 2.4
    import QtQuick.Controls 1.3
    import QtGraphicalEffects 1.0
    import SORTFILTERPROXYMODELL 1.0
    
    Item {
        id: root
        anchors.fill: parent
    
        Connections {
            target: controller
            onDoSetMenuItems: {
                listViewContextMenu.funcSetMenuItems(menuItemNameList)
            }
        }
    
        Component
        {
            id: columnComponent
            TableViewColumn{width: ( listView.width - 20 ) / 4; delegate: blankColumnDelegate}
        }
    
        TableView {
            id: listView
            anchors.top: header.bottom; anchors.left: parent.left; anchors.right: parent.right; anchors.bottom: parent.bottom
            model: proxyModelViewer.isSorting ? null : proxyModelViewer
            property bool hasCreatedColumns: false
    
            onCurrentRowChanged: {
                controller.onSelectionRowChanged(model.getData(listView.currentRow, "objectId"))
                selection.clear()
                selection.select(currentRow)
            }
    
            SortFilterProxyModell {
                id: proxyModelViewer
                objectName: "proxyModelViewer"
                source: listViewModel
    
                onSourceChanged:
                {
                    if (    (listViewModel != null) ||
                            (typeof(listViewModel) != "undefined"))
                    {
                        var roleList = userRoleNames
                        for (var columnIdx = 0; columnIdx < listView.columnCount; columnIdx++)
                        {
                            listView.removeColumn(columnIdx)
                        }
                        for (var roleIdx = 0; roleIdx < roleList.length; roleIdx++)
                       {
                            var role = roleList[roleIdx]
                            console.log("addColumn #" + roleIdx + "role=" + role)
                            var tvc = columnComponent.createObject({"role": role, "title": role})
                            listView.addColumn(tvc)
                        }
                    } 
                }
            }
    
            Component {
                id: rowDelegate
                Rectangle { id: rootRowDelegate
                    visible: model ? (styleData.row < proxyModelViewer.count) : false
                    MouseArea { id: delegateMouse
                        anchors.fill: parent; anchors.bottomMargin: listView.borderWidth
                        acceptedButtons: Qt.RightButton
                        onPressed: if (mouse.button === Qt.RightButton) {
                                        listViewContextMenu.popup()
                                        listView.currentRow = styleData.row  
                                   }
                    }
                }
            }
    
            Component {
                id: blankColumnDelegate
                Item { anchors.fill: parent }
            }
        }
    
        Menu { id: listViewContextMenu
            function funcSetMenuItems(menuItemNameList) {
                listViewContextMenu.clear()
                for (var menuItemIdx = 0; menuItemIdx < menuItemNameList.length; menuItemIdx++)
                {
                    var menuItemName = menuItemNameList[menuItemIdx];
                    var menuItemId = menuItemIdx;
                    var component = Qt.createComponent("ListViewContextMenuItem.qml");
                    var menuItem = component.createObject(listViewContextMenu, {"text": menuItemName, "thisMenuItemId": menuItemId});
                    listViewContextMenu.insertItem(menuItemId, menuItem);
                }
            }
    //    Old way of initializing the menu
    //    MenuItem {
    //        text: qsTr('Stuff')
    //        onTriggered: controller.doStuff()
    //    }
        }
    }
    

    Sorry for the wall of text, and thank you for any suggestions.

    Fabian



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.