qtqmlqt5qtquickcontrols2

OS Edit/Paste menu for Qt Quick.2 TextField


How do I get the OS specific paste menu for a QtQuick.Controls 2* TextField on a right click on selected text.

That works:

import QtQuick.Controls 1.4

TextField
{
    placeholderText: qsTr("Filter")
    selectByMouse: true
}

and gives me the menu, while

import QtQuick.Controls 2.2

TextField
{
    placeholderText: qsTr("Filter")
    selectByMouse: true
}

this does nothing on right-click.

I'm using version 5.9 LTS and I'm stuck with it for a while.

It works neither on Ubuntu Linux 16.04 with 5.9 manually installed nor on Windows 10, mingw{32,64} on msys2.


Solution

  • As far as I can see in the Qt bug tracker, it is a missing feature (QTBUG-35598), even in Qt 5.10.

    I think the reason for that IMHO, is to ensure the application has a consistent look and feel irregardless from the platform.

    So I'm afraid you have to implement your own context menu. Here is a snippet I came up with:

    property int selectStart
    property int selectEnd
    property int curPos
    
    TextField
    {
        id: textInput
        placeholderText: qsTr("Filter")
        selectByMouse: true
    
        MouseArea {
            anchors.fill: parent
            acceptedButtons: Qt.RightButton
            hoverEnabled: true
            onClicked: {
                selectStart = textInput.selectionStart;
                selectEnd = textInput.selectionEnd;
                curPos = textInput.cursorPosition;
                contextMenu.x = mouse.x;
                contextMenu.y = mouse.y;
                contextMenu.open();
                textInput.cursorPosition = curPos;
                textInput.select(selectStart,selectEnd);
            }
            onPressAndHold: {
                if (mouse.source === Qt.MouseEventNotSynthesized) {
                    selectStart = textInput.selectionStart;
                    selectEnd = textInput.selectionEnd;
                    curPos = textInput.cursorPosition;
                    contextMenu.x = mouse.x;
                    contextMenu.y = mouse.y;
                    contextMenu.open();
                    textInput.cursorPosition = curPos;
                    textInput.select(selectStart,selectEnd);
                }
            }
    
            Menu {
                id: contextMenu
                MenuItem {
                    text: "Cut"
                    onTriggered: {
                        textInput.cut()
                    }
                }
                MenuItem {
                    text: "Copy"
                    onTriggered: {
                        textInput.copy()
                    }
                }
                MenuItem {
                    text: "Paste"
                    onTriggered: {
                        textInput.paste()
                    }
                }
            }
        }
    }
    

    The code to save and restore the selection comes from KDE plasma (have look here) because by default TextField will reset the selection after right click.