强制 QPlainTextEdit 大写字符

Force QPlainTextEdit uppercase characters

我想在 QPlainTextEdit 中将输入的所有小写字符转换为大写字符。在 QLineEdit 中,我通过验证器执行相同操作,但似乎没有 QPlainTextEdit.

的验证器

我已经试过了 ui->pte_Route->setInputMethodHints(Qt::ImhUppercaseOnly); 但它什么也没做,很可能是用错了。

使用我的 "own" class 有更好的选择吗?

使用事件过滤器的快速测试似乎工作得相当好...

class plain_text_edit: public QPlainTextEdit {
  using super = QPlainTextEdit;
public:
  explicit plain_text_edit (QWidget *parent = nullptr)
    : super(parent)
    {
      installEventFilter(this);
    }
protected:
  virtual bool eventFilter (QObject *obj, QEvent *event) override
    {
      if (event->type() == QEvent::KeyPress) {
        if (auto *e = dynamic_cast<QKeyEvent *>(event)) {

          /*
           * If QKeyEvent::text() returns an empty QString then let normal
           * processing proceed as it may be a control (e.g. cursor movement)
           * key.  Otherwise convert the text to upper case and insert it at
           * the current cursor position.
           */
          if (auto text = e->text(); !text.isEmpty()) {
            insertPlainText(text.toUpper());

            /*
             * return true to prevent further processing.
             */
            return true;
          }
        }
      }
      return super::eventFilter(obj, event);
    }

如果它确实工作得足够好,那么事件过滤器代码总是可以单独提取以供重复使用。

为这样一个简单的任务使用事件过滤器看起来不是一个好主意,因为您被迫实现一个单独的 class 继承 QPlainTextEdit 或创建一些单独的 class 作为过滤器工作.相反,您还可以执行以下操作:

// Note. This is just a sample. Assume that 'this' is context of some class (e.g. class implementing QDialog/QMainWindow)
auto lineEdit = new QLineEdit();
/*
Here, you can use also &QLineEdit::textChanged, and it would not cause any Whosebug,
since Qt is pretty optimized here, i.e. if text does not change actually (value of QString
remains the same), Qt won't fire the signal. However, it is probably better to use
&QLineEdit::textEdited, since you expect the user to enter the text.
*/
connect(lineEdit, &QLineEdit::textEdited, this, [lineEdit](const QString& text)
{
    lineEdit->setText(text.toUpper());
});

换句话说,您可以通过Qt 为我们提供的简单信号和槽机制实现所需的相同行为。如果你可以通过标准的框架机制实现你想要的,那么你应该尝试这个而不是尝试实现事件过滤器,这可能会导致你甚至可能没有意识到的问题。请记住,事件过滤器是 Qt 提供的另一种机制,它使您可以更自由地做您想做的事,但您也必须处理更多的极端情况。

我遇到了 eventFilter 方法的问题,我使用了一个更简单的解决方案:

protected:
    void keyPressEvent(QKeyEvent* e) override {
        if (!e->text().isNull() && !e->text().isEmpty() &&
            e->modifiers() == Qt::NoModifier &&
            e->key() >= Qt::Key_A && e->key() <= Qt::Key_Z)
        {
            insertPlainText(e->text().toUpper());
        }
        else
            QPlainTextEdit::keyPressEvent(e);
    }

我正在使用继承自 QPlainTextEdit 的 Qt 示例中的 CodeEditor class。