Как реализовать отмену в наследнике QLineEdit?

Как использовать встроенную функциональность отмены / возврата QLineEdit при реализации пользовательской логики ввода?

Я внедряю собственный редактор для сумм денег для эффективной работы кассира. Основные функции:

  • Формат всегда ^\d+,\d{2}$;
  • Когда курсор оставлен на запятую, он редактирует целочисленную часть (например, когда редактируется 0,00, первый ввод цифры заменяет ноль; то есть 0,00 становится 1,00 после ввода «1»);
  • Введенная запятая или точка перемещает курсор к дробной части;
  • Удаляет и возвраты уважают формат.

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

Вопрос заключается в следующем: есть ли способ поддержки отмены в собственной логике QLineEdit? я использую setText(), который сбрасывает историю отмен / повторов. Я мог бы сделать два стека состояний и переопределить undo() а также redo() соответственно, или делать последовательности выборок и вставок / удалений (что может вызвать ненужные моргания), но я чувствую, что может быть даже более простой способ.

class MoneyLineEdit : public QLineEdit {
Q_OBJECT
public:
MoneyLineEdit(QWidget *parent = 0);

protected:
void keyPressEvent(QKeyEvent * event);
};

void MoneyLineEdit::keyPressEvent(QKeyEvent *event) {
if (event->key() == Qt::Key_Comma || event->key() == Qt::Key_Period) {
setCursorPosition(text().length() - 2);
} else {
QString text = this->text();
int pos = cursorPosition();
if (event->key() == Qt::Key_Backspace) {
if (pos == text.length()) {
text.replace(text.length() - 1, 1, QChar('0'));
--pos;
} else if (pos == text.length() - 1) {
text.replace(text.length() - 2, 1, text.at(text.length() - 1));
text.replace(text.length() - 1, 1, QChar('0'));
--pos;
} else if (pos == text.length() - 2) {
--pos;
} else if (text.length() == 4 && pos == 1) {
text.replace(0, 1, QChar('0'));
}
setText(text);
setCursorPosition(pos);
} else if ((pos == text.length() - 3 || pos == text.length() - 2) && event->key() == Qt::Key_Delete && selectionStart() == -1){
text.replace(text.length() - 2, 1, text.at(text.length() - 1));
text.replace(text.length() - 1, 1, QChar('0'));
setText(text);
setCursorPosition(pos);
} else if (pos >= text.length() - 2 && pos <= text.length() - 1 && !event->text().isEmpty()){
text.replace(cursorPosition(), 1, event->text());
++pos;
setText(text);
setCursorPosition(pos);
} else if ((pos == 0 || pos == 1) && !text.isEmpty() && text.length() == 4 && text.at(0) == QChar('0') && !event->text().isEmpty()) {
text.replace(0, 1, event->text());
setText(text);
setCursorPosition(1);
} else {
QLineEdit::keyPressEvent(event);
}
}
}

0

Решение

Очевидно, что два стека пары (text, cursorPosition) для undo()/redo() перегружены достаточно.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]