Qt 的復原與重做功能:

  • 基本功能
  • QUndoStack 巨集

Pyslvs 開發進度:

  • 復原與重做功能

Qt 的復原與重做功能

由於之前 Ubuntu 14.04 更新了 LiberOffice,沒想到 LiberOffice 的 Python 3.5 程式庫被 PyInstaller 錯認,導致在 Ubuntu 14.04 無法編譯出執行檔。

於是最近幾天裝了第三個系統 Ubuntu 16.04 來編譯,並且整理合併了原本雜亂的 Table Widget 管理用函式,為復原與重做功能。

參考資料:

基本功能

在 Qt 的程式中,使用下列類型管理指令以供復原。

  • QUndoGroup

    統整不同區域,如個別視窗、Widget。每個區域用 QUndoStack 紀錄。

  • QUndoStack

    統整不同的指令紀錄,如新增、刪除、編輯。每個指令用 QUndoCommand 紀錄。

  • QUndoCommand

    代表想要復原的指令,指令中可以包含其他 QUndoCommand。每個指令都要有下列方法。

    • Redo - QUndoCommand.redo()

      重做,可視為正指令,第一次呼叫會執行。

    • Undo - QUndoCommand.undo()

      復原,做出動作達成與 Redo 相反的狀態。

由於 QUndoCommand 在 QUndoStack 必須順序執行,因此在指定位置上用當前的位置考慮就好。如新增「最後一項」,Undo 時刪掉最後一項就好,不用擔心之後的指令造成這個項目不再是最後一項。

至於編輯和刪除,要先紀錄刪除前的狀態(儲存到子項目),才能在 Undo 時加回來。寫在 self.__init__() 即可,會比 Redo 早執行。

  • 呼叫 QUndoStack.push(QUndoCommand()) 方法來執行 QUndoCommand 的 Redo 項目,同時將 QUndoCommand 加入紀錄中。

  • 呼叫 QUndoStack.redo() 和 QUndoStack.undo() 方法來操作 QUndoCommand 的復原與重做。

要用 GUI 的方式查看並控制 QUndoStack,可以使用 QUndoView 這個 Widget。下面是一個只有 QUndoView 的 QDialog 懸浮窗,輸入對應的 stack 後,直接用滑鼠點擊可以馬上回到該階段。

class commandWindow(QDialog):
    def __init__(self, stack, parent=None):
        super(commandWindow, self).__init__(parent)
        undoView = QUndoView(stack)
        undoView.setEmptyLabel("Start.")
        undoView.setAttribute(Qt.WA_QuitOnClose, False)
        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(undoView)
        self.setWindowTitle("Command List")
        self.setSizeGripEnabled(False)
        size = QSize(250, 200)
        self.setMinimumSize(size)
        self.setMaximumSize(size)

QUndoStack 巨集

QUndoStack 的巨集功能幫開發者可以錄製多個 QUndoCommand 組成的指令。

原理就是建立一個空的 QUndoCommand,再將輸入的 QUndoCommand 建到這個指令下,在使用 count() 方法回傳命令數時,這種巨集只算 1 個指令。

使用 beginMacro() 方法時,該 QUndoStack 所有項目都會凍結,包含 undo() 都會無法使用,直到使用 endMacro()。

使用方式:

stack.beginMacro("複合指令") #開始錄製
stack.push(AFunction()) #紀錄第一個 QUndoCommand
print("複合指令執行中") #一般程式不會影響
stack.push(BFunction()) #紀錄第二個 QUndoCommand
stack.endMacro() #結束錄製

這樣下 undo() 方法就會一次倒敘 AFunction() 和 BFunction() 回去。

Pyslvs 開發進度

復原與重做功能

參照一些簡單的範例達成了復原功能,並且在 Command line 上的 print 字樣也有所標示。

不過還沒把一些更新功能轉成 QUndoCommand,所以暫時無法使用懸浮窗控制,全都加入後會預設啟用懸浮窗。

下圖是載入檔案後編輯連桿的長度。

使用 Ctrl + Z 復原。


Comments

comments powered by Disqus