作為一個例子,本例只實現了在列表控制元件“新增項”和“修改項名稱”的2個操作。介面上顯示一個列表框,列表框需要在介面設計器中設為IconMode,這樣就會是圖示在上文字在下的顯示樣式。“新增”按鈕用來在列表框中加一個項。點選圖示下面的文字可以修改文字名稱。程式測試環境是VS2017和Qt5.9,測試結果功能正常,執行效果如下:
標頭檔案:
class QListWidget; class MAddImage : public QUndoCommand { public: MAddImage(const QString &text, QListWidget* isrc, QUndoCommand *parent = Q_NULLPTR); ~MAddImage() override = default; void setActionInfo(const QPixmap& image, int where); void undo() override; void redo() override; private: QListWidget* src; QPixmap pixmap; int pos; }; class MChangeName : public QUndoCommand { public: MChangeName(const QString &text, QListWidget* isrc, QUndoCommand *parent = Q_NULLPTR); ~MChangeName() override = default; void setActionInfo(const QString& oldName, const QString& newName, int where); void undo() override; void redo() override; private: QListWidget* src; QString newText; QString oldText; int pos; };
CPP檔案:
MAddImage::MAddImage(const QString &text, QListWidget* isrc, QUndoCommand *parent) : QUndoCommand(text, parent) { src = isrc; } void MAddImage::setActionInfo(const QPixmap& image, int where) { pixmap = image; pos = where; } void MAddImage::undo() { delete src->takeItem(pos); } void MAddImage::redo() { QListWidgetItem* item = new QListWidgetItem(QIcon(pixmap), QString(u8"未命名")); item->setFlags(Qt::ItemIsEditable | item->flags()); src->insertItem(pos, item); } MChangeName::MChangeName(const QString &text, QListWidget* isrc, QUndoCommand *parent) : QUndoCommand(text, parent) { src = isrc; } void MChangeName::setActionInfo(const QString& oldName, const QString& newName, int where) { oldText = oldName; newText = newName; pos = where; } void MChangeName::undo() { src->blockSignals(true); QListWidgetItem* item = src->item(pos); item->setText(oldText); src->blockSignals(false); } void MChangeName::redo() { src->blockSignals(true); QListWidgetItem* item = src->item(pos); item->setText(newText); src->blockSignals(false); }
在主視窗類中有幾個槽函式需要實現以響應使用者的操作。下面的程式碼中QtTest是主視窗類;ui.lwList是列表控制元件;(ui.)pbAdd是“新增”按鈕;(ui.)pbUndo是“撤銷”按鈕;(ui.)pbRedo是“重做”按鈕。operas是QtTest類成員變數,定義是 QUndoStack operas; ,它是Qt封裝好的用於管理撤銷/重做命令的類,詳情可以查閱Qt幫助文件。
void QtTest::on_lwList_currentRowChanged(int row) { QListWidgetItem* it = ui.lwList->item(row); currEditText = it->text(); } void QtTest::on_lwList_itemChanged(QListWidgetItem *item) { MChangeName* changeAct = new MChangeName(u8"修改名稱", ui.lwList); changeAct->setActionInfo(currEditText, item->text(), ui.lwList->row(item)); operas.push(changeAct); /* 由於push(...)自動觸發redo()操作,因此這裡重新命名兩次 */ } void QtTest::on_pbAdd_clicked() { QPixmap pixmap(100, 80); pixmap.fill(QColor(qrand() % 255, qrand() % 255, qrand() % 255)); MAddImage* addAct = new MAddImage(u8"新增圖片", ui.lwList); addAct->setActionInfo(pixmap, ui.lwList->count()); operas.push(addAct); } void QtTest::on_pbUndo_clicked() { operas.undo(); } void QtTest::on_pbRedo_clicked() { operas.redo(); }