5

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.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
martin
  • 3,149
  • 1
  • 24
  • 35

2 Answers2

11

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.

Sergio Monteleone
  • 2,776
  • 9
  • 21
1

I don't recommend using MouseArea to open the menu, it causes the TextArea's hover effect unavailable. I've looked into this problem and if you use TapHandler instead, this will involve a qt bug: TapHandler on TextField (for showing right click context menu) stops working in Qt6 which will prevent you from using TapHandler unless you are on version 6.4.2 or above.

The most appropriate method to use is to use onPressed or onReleased in the TextArea, it works fine.

onPressed: function(mouse) {
    if (mouse.button != Qt.RightButton) return
    var point = mapToGlobal(mouse.x, mouse.y)
    textArea.showMenu(point.x, point.y) //custom method to show Menu
}

I hope this will be of help to those who come after me

0ices
  • 35
  • 9