Я хочу преобразовать все строчные буквы при вводе в верхний регистр в QPlainTextEdit. В QLineEdit я делаю то же самое с помощью валидатора, но, кажется, нет валидатора для QPlainTextEdit.

Я пытался ui->pte_Route->setInputMethodHints(Qt::ImhUppercaseOnly);, но он ничего не делает, скорее всего, неправильно.

Любой лучший вариант, как использование моего "собственного" класса?

1
Horst Walter 12 Апр 2019 в 20:16

2 ответа

Лучший ответ

Быстрый тест с использованием фильтра событий, кажется, работает достаточно хорошо ...

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

Если он работает достаточно хорошо, тогда код фильтра событий всегда можно извлечь отдельно для повторного использования.

1
G.M. 13 Апр 2019 в 07:56

Использование фильтров событий для такой простой задачи не выглядит хорошей идеей, поскольку вы вынуждены реализовать либо отдельный класс, наследующий QPlainTextEdit, либо создать какой-то отдельный класс, работающий в качестве фильтра. Вместо этого вы также можете сделать следующее:

// 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 stackoverflow,
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, который дает вам больше свободы делать то, что вы хотите делать, но также вы должны принимать гораздо более важные случаи.

1
Vaidotas Strazdas 15 Апр 2019 в 15:19