如何在QLineEdit继承人中实现撤销?

时间:2013-08-12 08:23:31

标签: c++ qt currency undo-redo qlineedit

如何在实现自定义输入逻辑时使用QLineEdit的内置撤消/重做功能?

我正在为收银员的高效工作实施一笔自定义编辑器。基本功能是:

  • 格式始终为^\d+,\d{2}$;
  • 当光标留给逗号时,它编辑整数部分(例如,当编辑0,00时,第一个数字输入替换零;即,在输入'1'后0,00变为1,00);
  • 输入的逗号或句点将光标移动到小数部分;
  • 删除和退格符合格式。

我不能使用蒙版,因为它们无法管理任意长度而没有不必要的空格。我不能使用验证器,因为它们不够灵活,无法处理编辑前导零的逻辑。这就是为什么我将QLineEdit细分为自己并写下了必要的逻辑。

问题是:有没有办法在QLineEdit自己的逻辑上支持撤销功能?我使用setText()来重置撤消/重做历史记录。我可以制作两个状态堆栈并相应地覆盖undo()redo(),或者进行选择和插入/删除的序列(什么可能导致不必要的闪烁),但我觉得可能有更简单的方法。 / p>

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

1 个答案:

答案 0 :(得分:0)

显然,undo()/redo()重载的两个Pair(text,cursorPosition)堆栈就足够了。