In the sources, I notice there is quite the comprehensive set of cursor control operations:
enum MoveOperation {
NoMove,
Start,
Up,
StartOfLine,
StartOfBlock,
StartOfWord,
PreviousBlock,
PreviousCharacter,
PreviousWord,
Left,
WordLeft,
End,
Down,
EndOfLine,
EndOfWord,
EndOfBlock,
NextBlock,
NextCharacter,
NextWord,
Right,
WordRight,
NextCell,
PreviousCell,
NextRow,
PreviousRow
};
In contrast, the latest TextField
from QtQuick.Controls 1.4
, the cursor position is exposed as a simple integer, which can be set, but without specifying any of those move operations. And that's about it.
In the older TextEdit
there is some extra stuff like selectWord()
and moveCursorSelection(int position, SelectionMode mode)
, but mode
is limited to either selecting characters or words.
What's worse, the sparse existing APIs don't really provide the necessary functionality to manually re-implement most of those modes.
So, thins brings me to the question, which is how to get all that that functionality in QML in the most straightforward and least obtrusive way?
Update:
There is actually a more obvious and less intrusive way to get that functionality, and it is by posting fake events to the desired text edit. This had the advantage of not requiring to use private APIs, thus avoiding all the potential build and compatibility complications:
void postKeyEvent(Qt::Key k, QObject * o, bool sh = false, bool ct = false, bool al = false) {
uint mod = Qt::NoModifier;
if (sh) mod |= Qt::ShiftModifier;
if (ct) mod |= Qt::ControlModifier;
if (al) mod |= Qt::AltModifier;
QCoreApplication::postEvent(o, new QKeyEvent(QEvent::KeyPress, k, (Qt::KeyboardModifier)mod));
QTimer::singleShot(50, [=]() { QCoreApplication::postEvent(o, new QKeyEvent(QEvent::KeyRelease, k, (Qt::KeyboardModifier)mod)); });
}
Now I can finally get all the needed cursor control stuff with my custom virtual keyboard on touch devices.
This is one simple solutions which actually works... if you manage to build it, there are some odd problems with building it :
#include <QtQuick/private/qquicktextedit_p.h>
#include <QtQuick/private/qquicktextedit_p_p.h>
#include <QtQuick/private/qquicktextcontrol_p.h>
class CTextEdit : public QQuickTextEdit {
Q_OBJECT
public:
CTextEdit(QQuickItem * p = 0) : QQuickTextEdit(p) {}
public slots:
void cursorOp(int mode) {
QQuickTextEditPrivate * ep = reinterpret_cast<QQuickTextEditPrivate *>(d_ptr.data());
QTextCursor c = ep->control->textCursor();
c.movePosition((QTextCursor::MoveOperation)mode);
ep->control->setTextCursor(c);
}
};
Obviously it uses private headers, which has two implications:
quick-privte
module to the PRO file _
Project MESSAGE: This project is using private headers and will therefore be tied to this specific Qt module build version.
Project MESSAGE: Running this project against other versions of the Qt modules may crash at any arbitrary point.
Project MESSAGE: This is not a bug, but a result of using Qt internals. You have been warned!
On the upside, it works like a charm. IMO that functionality should have been available as a part of the public API to begin with, it is quite useful and certainly not something that makes sense to be hidden away.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.