简体   繁体   English

从QML获得对文本光标的更多控制

[英]Get more control over text cursor from QML

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. 相反,来自QtQuick.Controls 1.4的最新TextField ,光标位置显示为一个简单的整数,可以设置该整数,但不指定任何这些移动操作。 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. 在较早的TextEdit还有一些额外的东西,例如selectWord()moveCursorSelection(int position, SelectionMode mode) ,但是mode仅限于选择字符或单词。

What's worse, the sparse existing APIs don't really provide the necessary functionality to manually re-implement most of those modes. 更糟糕的是,稀疏的现有API并没有真正提供手动重新实现大多数模式所需的功能。

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? 因此,thins使我想到一个问题,即如何以最直接,最不引人注目的方式获得QML中的所有功能?

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: 这样做的好处是不需要使用私有API,从而避免了所有潜在的构建和兼容性复杂性:

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: 显然,它使用私有头,这有两个含义:

  • you will have to add the quick-privte module to the PRO file 您将必须将quick-privte模块添加到PRO文件中
  • private stuff is subject to changes, including breaking changes, as this friendly message keeps reminding: 私人信息可能会发生变化,包括重大更改,因为此友好消息不断提醒您:

_ _

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. IMO认为,功能应该作为公共API的一部分开始可用,它非常有用,当然,隐藏起来没有什么意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM