Qt 5.8 brings some more support of Text Selection Handles, but there are still also some problems. Text Selection Handles are important to make it easy on touch devices to insert text, copy text, replace text or cut text. With 5.7 single taps to get a handle to move the insert position around already works.
Select words by double tap
Qt 5.8 also supports double tap to select words – but it doesn’t work as expected. This selection mode will only be enabled if you set
selectByMouse: true
on TextField or TextArea. This works fine with TextFields, but having TextArea inside Flickable makes scrolling difficult or impossible. Qt doesn’t know if you want to change the selection or scroll inside the TextField or scroll the Page. Users will be confused and it’s not easy to know where outside the Textfield scrolling works. Hopefully in Qt 5.9 this will befixed and double tap works without setting ‘selectByMouse’.
One of my app contains many TextAreas and users are waiting for word-selection-mode, so I developed some workarounds for 5.8.
To make it easier to distinguish where’s the TextArea I placed the TextArea on top of a Pane. Now you can tell your user to scroll the Page place fingers outside the TextArea:
As soon as TextArea gets active focus, 3 buttons will appear on the right side:
- clear
- toggle selection mode
- done
As soon as the user does a double-tap on a word both text selection handlers become visible and it’s easy to move them around to select more or less.
Also please notice on top a menu to select all, cut, copy and paste.
On iOS this is different: at first do the double tap to select a word – then please do a long press on the selection to get a cut, copy, paste, delete menu just on top of the selection:
Single tap does work with or without setting ‘selectByMouse’:
To insert from clipboard do a long-press: ‘insert’ menu appears on top of cursor position.
Tap on the Toggle Button to set selectByMouse = false to make it easier to scroll also while inside the Textfield.
When you’re ready with text editing tap on the ‘Done’ Button. Done Button gets focus and all Handles disappear. Also Done and Toggle Button disappear.
As long as there’s some text, the clear Button makes it easy to clear the field:
Here’s the workaround. I placed all of this into ‘TextAreaRow.qml’ – then it will be easy to change when 5.9 comes out.
TextAreaRow{ id: remarksTextRow placeholderText: qsTr("Your Remarks (RETURN for new line)") text: tourDetail.remark onTextChanged: { tourDetail.remark = text } onDone: { // do something: set active focus to another field or so } } // remarksTextRow
And here’s the implementation:
RowLayout { id: theTextRow signal done() property alias text: theTextField.text property alias placeholderText: theTextField.placeholderText property alias textField: theTextField property int minHeightTextPane: 140 property bool doubleTapIsDefault: true Pane { id: textPane anchors.top: parent.top Material.elevation: 6 Layout.fillWidth: true Layout.minimumHeight: theTextField.activeFocus? minHeightTextPane : 60 TextArea { id: theTextField // Qt 5.8 // only if set to true we can mark words by double tap selectByMouse: doubleTapIsDefault // important - otherwise text goes endless without wrapping width: parent.width text: "" wrapMode: TextArea.WordWrap } // theTextField } // text pane Column { spacing: 0 anchors.top: textPane.top Layout.minimumWidth: textClearButton.visible || textSelectToggleButton.visible || textDoneButton.visible? 48 : 0 ButtonIconActive { id: textClearButton anchors.horizontalCenter: parent.horizontalCenter visible: theTextField.activeFocus || theTextField.text.length focusPolicy: Qt.ClickFocus imageName: "clear.png" onClicked: { theTextField.text = "" } } // textClearButton ButtonIconActive { id: textSelectToggleButton anchors.horizontalCenter: parent.horizontalCenter visible: theTextField.activeFocus focusPolicy: Qt.ClickFocus imageName: "code.png" onClicked: { theTextField.selectByMouse = !theTextField.selectByMouse if(theTextField.selectByMouse) { appWindow.showToast(qsTr("Word Selection by Double Tap switched ON")) } else { appWindow.showToast(qsTr("Word Selection by Double Tap switched OFF")) } } } // textSelectButton ButtonIconActive { id: textDoneButton anchors.horizontalCenter: parent.horizontalCenter visible: theTextField.activeFocus focusPolicy: Qt.ClickFocus imageName: "done.png" onClicked: { // we only need the focus // emit signal so users can give another field the activeFocus theTextRow.done() } } // textDoneButton } } // row w text area
ButtonIconActive is a customized Button showing Icon. You’ll find all of this in my sample apps at Github – I also have updated QtWorldSummit Conference App.
On Android there are two bugs:
Selection handles overlap while scrolling (Android only)
The selection handle(s) can overlap the keyboard or selection menu:
—
Take a look at BUG 58700
Selection Handle visible when Component invisible
If the Component containing your TextField or TextArea becomes invisible and the TextField still has active focus, the handles will still be visible.
See BUG 58700
Workaround is easy: set focus to another field as soon as TextField becomes invisible.
Thank you so much
Still waiting for the promised push notifications in Qt. This is one of the most critical pieces in Qt mobile dev. Please come up with that tutorial.
for the push notifications see these tutorials:
https://gympulsr.com/blog/qt/2017/03/08/push-notification-ios-qt.html
https://gympulsr.com/blog/qt/2017/03/26/push-notification-android-qt.html
and the discussion here: https://forum.qt.io/topic/76826/gcm-push-notifications-android
Thanks. I had already been through those links, I just haven’t given them a try yet, but I will soon.
later this year I’ll also add an own example app with push notifications (or add this to the upcoming QtWorldSummit 2017 Conference APP)
at the moment just have developed Bluetooth LE example app. (blog and public repo will follow soon)
Can’t wait already! I always go though this blog from time to time just to get up to date with the current developments. Thanks a lot for the effort you have put for the benefit of us all.