【问题标题】:Get more control over text cursor from QML从 QML 获得对文本光标的更多控制
【发布时间】:2017-08-27 11:19:19
【问题描述】:

在源代码中,我注意到有相当全面的光标控制操作集:

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
};

相比之下,来自QtQuick.Controls 1.4 的最新TextField,光标位置公开为一个简单的整数,可以设置,但无需指定任何移动操作。就是这样。

在较旧的TextEdit 中有一些额外的内容,例如selectWord()moveCursorSelection(int position, SelectionMode mode),但mode 仅限于选择字符或单词。

更糟糕的是,现有的稀疏 API 并没有真正提供必要的功能来手动重新实现大多数这些模式。

所以,thins 给我带来了一个问题,即如何以最直接和最不突兀的方式在 QML 中获得所有这些功能?

【问题讨论】:

  • 你也应该向 Qt 兴趣邮件列表询问这个
  • @Jean-MichaëlCelerier 是的,或者向上帝祈祷 :) 我现在实际上已经完成了一半,除了一个小的链接问题。

标签: c++ qt text cursor qml


【解决方案1】:

更新:

实际上有一种更明显且干扰更少的方法来获得该功能,它是将虚假事件发布到所需的文本编辑中。这样做的好处是不需要使用私有 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)); });
}

现在,我终于可以在触控设备上使用自定义虚拟键盘​​获得所有需要的光标控制功能了。


这是一个实际可行的简单解决方案......如果你设法构建它,有一些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);
    }
};

显然它使用私有标头,这有两个含义:

  • 您必须将 quick-privte 模块添加到 PRO 文件中
  • 私人内容可能会发生变化,包括重大变化,因为这条友好的消息不断提醒:

_

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!

从好的方面来说,它就像一个魅力。 IMO,该功能一开始就应该作为公共 API 的一部分提供,它非常有用,当然隐藏起来毫无意义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    相关资源
    最近更新 更多