class CustomTimer(QLCDNumber): def __init__(self, interval: int, parent=None): super(CustomTimer, self).__init__(parent) self.time = QTime() self.interval = interval p = self.palette() p.setColor(QPalette.Background, Qt.black) p.setColor(p.Light, Qt.darkRed) self.setPalette(p) self.timer = None def timerEvent(self, event: QTimerEvent): self.display(int(self.time.elapsed() / self.interval)) def start(self): self.timer = self.startTimer(int(self.interval / 2)) self.time.start() def stop(self): if self.timer is not None: self.killTimer(self.timer) def reset(self): self.display(0)
def timeWorker(self): """ Updateting elapsed time. """ timer = QTime() timer.start() self.breaker = 0 while self.breaker != 1: time.sleep(1) m, s = divmod(timer.elapsed() // 1000, 60) h, m = divmod(m, 60) self.lblTime.setText("%d:%02d:%02d" % (h, m, s))
def playResult(self): if self.result != None: cnt = 1 for step in self.result: if type(step) == np.ndarray: self.setArray(step) else: file = open('tmp', 'w') step = step.replace('[', '').replace(']', '') file.write(step) file.close() self.setArray(np.loadtxt('tmp').astype(int), preText='(' + str(cnt) + '/' + str(len(self.result)) + ')') cnt = cnt + 1 t = QTime() t.start() while t.elapsed() < 100: # 0.1s/步切换 QApplication.processEvents()
def run(self): t = QTime() t.start() time.sleep(2) # Sleep 2 seconds
class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.undoStack = QUndoStack(self) self.undoStack.cleanChanged.connect(self.cleanChanged) self.undoAction = self.undoStack.createUndoAction(self, "&Undo") self.undoAction.setShortcut(QKeySequence.Undo) self.redoAction = self.undoStack.createRedoAction(self, "&Redo") self.redoAction.setShortcut(QKeySequence.Redo) self.messageLabel = QLabel() self.coordLabel = QLabel() self.stopwatchLabel = QLabel() self.time = QTime(0, 0) self.stopwatch = QTimer() self.undoView = QUndoView(self.undoStack) self.graphicsScene = GraphicsScene(self) self.copyList = [] def setupUi(self): if QIcon.themeName() == "": QIcon.setThemeName('breeze') self.openIcon = QIcon().fromTheme("document-open") self.actionOpen_Datasets.setIcon(self.openIcon) self.saveIcon = QIcon().fromTheme("document-save") self.actionSave.setIcon(self.saveIcon) self.closeIcon = QIcon().fromTheme("document-close") self.actionClose_Dataset.setIcon(self.closeIcon) self.statusbar.addWidget(self.messageLabel) self.statusbar.addWidget(self.coordLabel) self.statusbar.addWidget(self.stopwatchLabel) self.stopwatch.setInterval(1000) self.stopwatch.timeout.connect(self.updateStopWatchLabel) self.stopwatchStartIcon = QIcon().fromTheme("chronometer-start") self.actionTimer_Start.setIcon(self.stopwatchStartIcon) self.actionTimer_Start.triggered.connect(self.startStopWatch) self.stopwatchStopIcon = QIcon().fromTheme("chronometer-pause") self.actionTimer_Stop.setIcon(self.stopwatchStopIcon) self.actionTimer_Stop.triggered.connect(self.stopStopWatch) self.stopwatchResetIcon = QIcon().fromTheme("chronometer-reset") self.actionTimer_Reset.setIcon(self.stopwatchResetIcon) self.actionTimer_Reset.triggered.connect(self.resetStopWatch) self.leftIcon = QIcon().fromTheme("go-previous") self.actionSend_To_Left.setIcon(self.leftIcon) self.rightIcon = QIcon().fromTheme("go-next") self.actionSend_To_Right.setIcon(self.rightIcon) self.upIcon = QIcon().fromTheme("go-up") self.actionPrevious_Item.setIcon(self.upIcon) self.downIcon = QIcon().fromTheme("go-down") self.actionNext_Item.setIcon(self.downIcon) self.undoView.setWindowTitle("Command List") self.undoView.show() self.undoView.setAttribute(Qt.WA_QuitOnClose, False) self.menuEdit.addAction(self.undoAction) self.menuEdit.addAction(self.redoAction) self.graphicsView.setScene(self.graphicsScene) self.graphicsView.mouseMoved.connect(self.coordLabel.setText) self.graphicsScene.tabWidget = self.tabWidget self.graphicsScene.comboBox = self.comboBox self.graphicsScene.signalHandler.boxPressed.connect(self.selectBox) self.graphicsScene.signalHandler.boxChanged.connect(self.changeBox) self.graphicsScene.signalHandler.boxCreated.connect(self.createItem) @Slot() def sendToLeft(self): originIndex = self.tabWidget.currentIndex() numTabs = self.tabWidget.count() targetIndex = (numTabs + originIndex - 1) % numTabs modelIndex = self.tabWidget.getCurrentTableView().currentIndex() if modelIndex.isValid(): self.undoStack.beginMacro(f"Send item to {targetIndex}") sendToCommand = SendToCommand(originIndex, targetIndex, modelIndex.row(), self.tabWidget, self.graphicsScene) self.undoStack.push(sendToCommand) modelIndex = modelIndex.model().index(modelIndex.row(), modelIndex.column()) if modelIndex.isValid(): self.cellClicked(originIndex, modelIndex, originIndex, modelIndex) self.undoStack.endMacro() @Slot() def sendToRight(self): originIndex = self.tabWidget.currentIndex() numTabs = self.tabWidget.count() targetIndex = (originIndex + 1) % numTabs modelIndex = self.tabWidget.getCurrentTableView().currentIndex() if modelIndex.isValid(): self.undoStack.beginMacro(f"Send item to {targetIndex}") sendToCommand = SendToCommand(originIndex, targetIndex, modelIndex.row(), self.tabWidget, self.graphicsScene) self.undoStack.push(sendToCommand) modelIndex = modelIndex.model().index(modelIndex.row(), modelIndex.column()) if modelIndex.isValid(): self.cellClicked(originIndex, modelIndex, originIndex, modelIndex) self.undoStack.endMacro() @Slot() @Slot(int) def closeDataset(self, i=-1): # put a dialog if there is a pending modification # say that modifications are not lost and retrievable with CTRL-Z if self.tabWidget.count() > 0: if i == -1: i = self.tabWidget.currentIndex() deleteDatasetCommand = DeleteDatasetCommand([i], self.tabWidget, self.comboBox, self.graphicsView, self.graphicsScene) self.undoStack.push(deleteDatasetCommand) @Slot() def openDatasets(self): """Open dataset directory""" prevTabIndex = self.tabWidget.currentIndex() prevModelIndex = self.tabWidget.getCurrentSelectedCell() numTabs = self.tabWidget.count() (filenames, _ext) = QFileDialog.getOpenFileNames( self, QApplication.translate("MainWindow", "Open datasets", None, -1), "/home/kwon-young/Documents/PartageVirtualBox/data/omr_dataset/choi_dataset", "*.csv") if filenames: self.undoStack.beginMacro(f"open Datasets {filenames}") filenames.sort() openDatasetCommand = OpenDatasetCommand(filenames, self.tabWidget, self.comboBox, self.graphicsScene, self.messageLabel) self.undoStack.push(openDatasetCommand) tabIndex = numTabs if self.tabWidget.count() > 0: modelIndex = self.tabWidget.getTableModel(tabIndex).index(0, 0) if modelIndex.isValid(): self.cellClicked(tabIndex, modelIndex, prevTabIndex, prevModelIndex) self.undoStack.endMacro() @Slot(int) def currentTabChanged(self, index): self.tabWidget.setCurrentIndex(index) for tabIndex in range(self.tabWidget.count()): self.graphicsScene.changeTabColor( tabIndex, self.tabWidget.color_map(tabIndex)) @Slot(int, QModelIndex, int, QModelIndex) def cellClicked(self, tabIndex, cellIndex, prevTabIndex, prevCellIndex): cellClickedCommand = CellClickedCommand( tabIndex, cellIndex, prevTabIndex, prevCellIndex, self.tabWidget, self.graphicsScene, self.graphicsView, self.comboBox, self.messageLabel) self.undoStack.push(cellClickedCommand) @Slot() def SelectNextItem(self): if self.tabWidget.count() > 0: tabIndex = self.tabWidget.currentIndex() prevCellIndex = self.tabWidget.getCurrentSelectedCell() model = self.tabWidget.getCurrentTableModel() rowCount = model.rowCount(QModelIndex()) nextRow = (prevCellIndex.row() + 1) % rowCount cellIndex = model.index(nextRow, prevCellIndex.column()) cellClickedCommand = CellClickedCommand( tabIndex, cellIndex, tabIndex, prevCellIndex, self.tabWidget, self.graphicsScene, self.graphicsView, self.comboBox, self.messageLabel) self.undoStack.push(cellClickedCommand) @Slot() def SelectPreviousItem(self): if self.tabWidget.count() > 0: tabIndex = self.tabWidget.currentIndex() prevCellIndex = self.tabWidget.getCurrentSelectedCell() model = self.tabWidget.getCurrentTableModel() rowCount = model.rowCount(QModelIndex()) nextRow = (rowCount + prevCellIndex.row() - 1) % rowCount cellIndex = model.index(nextRow, prevCellIndex.column()) cellClickedCommand = CellClickedCommand( tabIndex, cellIndex, tabIndex, prevCellIndex, self.tabWidget, self.graphicsScene, self.graphicsView, self.comboBox, self.messageLabel) self.undoStack.push(cellClickedCommand) @Slot() def SelectNextPage(self): if self.tabWidget.count() > 0: tabIndex = self.tabWidget.currentIndex() prevCellIndex = self.tabWidget.getCurrentSelectedCell() model = self.tabWidget.getCurrentTableModel() prevPage = model.pageAtIndex(prevCellIndex) rowCount = model.rowCount(QModelIndex()) for i in range(0, rowCount): row = (prevCellIndex.row() + i) % rowCount cellIndex = model.index(row, prevCellIndex.column()) page = model.pageAtIndex(cellIndex) if prevPage.split("-")[0] != page.split("-")[0]: break cellClickedCommand = CellClickedCommand( tabIndex, cellIndex, tabIndex, prevCellIndex, self.tabWidget, self.graphicsScene, self.graphicsView, self.comboBox, self.messageLabel) self.undoStack.push(cellClickedCommand) @Slot() def SelectPreviousPage(self): if self.tabWidget.count() > 0: tabIndex = self.tabWidget.currentIndex() prevCellIndex = self.tabWidget.getCurrentSelectedCell() model = self.tabWidget.getCurrentTableModel() prevPage = model.pageAtIndex(prevCellIndex) rowCount = model.rowCount(QModelIndex()) for i in range(0, rowCount): row = (prevCellIndex.row() - i) % rowCount cellIndex = model.index(row, prevCellIndex.column()) page = model.pageAtIndex(cellIndex) if prevPage.split("-")[0] != page.split("-")[0]: break cellClickedCommand = CellClickedCommand( tabIndex, cellIndex, tabIndex, prevCellIndex, self.tabWidget, self.graphicsScene, self.graphicsView, self.comboBox, self.messageLabel) self.undoStack.push(cellClickedCommand) @Slot() def selectNextLabel(self): if self.comboBox.count() > 0: index = self.comboBox.currentIndex() newIndex = (index + 1) % self.comboBox.count() label = self.comboBox.itemText(newIndex) tabIndex = self.tabWidget.currentIndex() cellIndex = self.tabWidget.getCurrentSelectedCell() labelChangedCommand = LabelChangedCommand(label, tabIndex, cellIndex, self.tabWidget, self.graphicsScene, self.comboBox) self.undoStack.push(labelChangedCommand) @Slot() def selectPreviousLabel(self): if self.comboBox.count() > 0: index = self.comboBox.currentIndex() newIndex = ((self.comboBox.count() + index - 1) % self.comboBox.count()) label = self.comboBox.itemText(newIndex) tabIndex = self.tabWidget.currentIndex() cellIndex = self.tabWidget.getCurrentSelectedCell() labelChangedCommand = LabelChangedCommand(label, tabIndex, cellIndex, self.tabWidget, self.graphicsScene, self.comboBox) self.undoStack.push(labelChangedCommand) @Slot(int) def labelChanged(self, index): label = self.comboBox.itemText(index) tabIndex = self.tabWidget.currentIndex() cellIndex = self.tabWidget.getCurrentSelectedCell() labelChangedCommand = LabelChangedCommand(label, tabIndex, cellIndex, self.tabWidget, self.graphicsScene, self.comboBox) self.undoStack.push(labelChangedCommand) @Slot() def saveDataToDisk(self): self.undoStack.setClean() for name, model in zip(self.tabWidget.filenames(), self.tabWidget.models()): model.save(name) @Slot(bool) def cleanChanged(self, clean): self.setWindowModified(not clean) @Slot(int, int) def selectBox(self, tabIndex, rowIndex): if tabIndex != self.tabWidget.currentIndex() or \ rowIndex != self.tabWidget.getCurrentSelectedCell().row(): selectBoxCommand = SelectBoxCommand(tabIndex, rowIndex, self.tabWidget, self.graphicsScene, self.comboBox) self.undoStack.push(selectBoxCommand) @Slot(int, int, QRectF) def changeBox(self, tabIndex, rowIndex, box): moveBoxCommand = MoveBoxCommand(tabIndex, rowIndex, box, self.tabWidget, self.graphicsScene) self.undoStack.push(moveBoxCommand) @Slot(QRectF, QRectF) def viewportMoved(self, rect, prevRect): viewportMovedCommand = ViewportMovedCommand(rect, prevRect, self.graphicsView) self.undoStack.push(viewportMovedCommand) @Slot() def updateStopWatchLabel(self): elapsed = QTime(0, 0).addMSecs(self.time.elapsed()) self.stopwatchLabel.setText(elapsed.toString()) @Slot() def startStopWatch(self): self.time.start() self.stopwatch.start(1000) @Slot() def stopStopWatch(self): self.stopwatch.stop() @Slot() def resetStopWatch(self): self.time.start() self.stopwatchLabel.setText(QTime(0, 0).toString()) @Slot() def deleteItem(self): tabIndex = self.tabWidget.currentIndex() cellIndex = self.tabWidget.getCurrentSelectedCell() self.undoStack.beginMacro(f"Delete item {tabIndex}:{cellIndex.row()}") deleteItemCommand = DeleteItemCommand(tabIndex, cellIndex, self.tabWidget, self.graphicsView, self.graphicsScene, self.comboBox) self.undoStack.push(deleteItemCommand) cellIndex = cellIndex.model().index(cellIndex.row(), cellIndex.column()) if cellIndex.isValid(): self.cellClicked(tabIndex, cellIndex, tabIndex, cellIndex) self.undoStack.endMacro() @Slot(ResizableRect) def createItem(self, rect): self.undoStack.beginMacro( f"Create item {rect.tabIndex}:{rect.rowIndex}") createItemCommand = CreateItemCommand(rect, self.tabWidget, self.graphicsScene, self.comboBox) self.undoStack.push(createItemCommand) self.selectBox(rect.tabIndex, rect.rowIndex) self.undoStack.endMacro() @Slot() def tabItemForward(self): changeTabItemZValueCommand = ChangeTabItemZValueCommand( self.tabWidget.currentIndex(), 1, self.graphicsScene) self.undoStack.push(changeTabItemZValueCommand) @Slot() def tabItemBackward(self): changeTabItemZValueCommand = ChangeTabItemZValueCommand( self.tabWidget.currentIndex(), -1, self.graphicsScene) self.undoStack.push(changeTabItemZValueCommand) @Slot() def copy(self): tabIndex = self.tabWidget.currentIndex() cellIndex = self.tabWidget.getCurrentSelectedCell() box = self.graphicsScene.box(tabIndex, cellIndex.row()) copyCommand = CopyCommand(box, self.copyList) self.undoStack.push(copyCommand) @Slot() def paste(self): pos = self.graphicsView.mapFromGlobal(QCursor.pos()) scenePos = self.graphicsView.mapToScene(pos) prop = self.copyList[-1] self.undoStack.beginMacro(f"paste item {prop.box}") pasteCommand = PasteCommand(scenePos, prop, self.tabWidget, self.graphicsScene) self.undoStack.push(pasteCommand) self.selectBox(prop.tabIndex, prop.rowIndex) self.undoStack.endMacro()
class NetworkConnectionClass(QtCore.QObject): SignalDataRec = Signal(str, int) SignalFrameDataAvailable = Signal() def __init__(self, parent=None): super(NetworkConnectionClass, self).__init__(parent=parent) #self.CommandSocket = QTcpSocket() self.CommandSocket = QUdpSocket() self.CommandSocket.bind(QHostAddress("192.168.100.2"), 2323) self.CommandSocket.connected.connect(self.EventConnectedHandle) self.CommandSocket.readyRead.connect(self.RecieveData) #self.CommandSocket.connectToHost("192.168.100.5",2323,QIODevice.ReadWrite) #self.CommandSocket.connectToHost("127.0.0.1",2323,QIODevice.ReadWrite) #self.CommandSocket.connectToHost("192.168.20.196",2323,QIODevice.ReadWrite) #print("NETWORK - ",self.CommandSocket.localAddress(),self.CommandSocket.peerAddress()) self.Display = WindowNetworkConnection() self.NetworkDataArray = QByteArray() self.NetworkDataArray.resize(2000) self.SignalDataRec.connect(self.Display.PrintData) self.BufferWrite = QBuffer(self.NetworkDataArray) self.BufferWrite.open(QBuffer.WriteOnly) self.BufferRead = QBuffer(self.NetworkDataArray) self.BufferRead.open(QBuffer.ReadOnly) self.ReadDataStream = QDataStream(self.BufferRead) self.ReadDataStream.setByteOrder(QDataStream.LittleEndian) self.WriteDataStream = QDataStream(self.BufferWrite) self.WriteDataStream.setByteOrder(QDataStream.LittleEndian) self.SocketDataStream = QDataStream(self.CommandSocket) self.SocketDataStream.setByteOrder(QDataStream.LittleEndian) self.Timer = QTime() self.Timer.start() self.BufferRead.seek(0) self.BufferWrite.seek(0) self.LimitBufferSize = 2000 self.MinTransferUnit = 7 self.MaxTransferUnit = 18 self.bytesAvailable = 0 self.Display.ui.pushButton.clicked.connect(self.SendData) #===================================================== WRITE BUFFER self.SendBuffer = QByteArray() #===================================================== # TestMessage = QByteArray(bytearray.fromhex('A1 A2 A3')); TestMessage2 = QByteArray(bytearray.fromhex('A4 A5 A6')) # self.BufferWriteQueue.write(TestMessage); self.BufferWriteQueue.write(TestMessage2) # print("BUFFER - ",self.NetworkDataArray) # self.Message = MessageData() # self.Message << self.NetworkDataStream << self.NetworkDataStream def __rshift__(self, Reciever: DataTransferHeader): Reciever << self.ReadDataStream self.bytesAvailable -= Reciever.UNIT_SIZE print("BYTES AVAILABLE - ", self.bytesAvailable) #print(" REABUFFER POS - ",self.BufferRead.pos(),'BYTES AVAILABLE - ',self.bytesAvailable,"UNIT SIZE -",Reciever.UNIT_SIZE) #print(" READ UNIT -",Reciever.UNIT_SIZE) #print(" READ BUFFER POS -",self.BufferRead.pos()) #print(" READ BUFFER -",self.BufferRead.data().toHex()) if not self.BufferRead.pos( ) < self.LimitBufferSize - self.MaxTransferUnit: self.BufferRead.seek(0) print("READ BUFFER SEEK TO 0 - ", self.BufferRead.pos()) return self def EventConnectedHandle(self): self.SignalDataRec.emit("CONNECTED TO HOST", 0) #self.SignalDataRec.emit("192.168.100.5 PORT 2323",0) self.SignalDataRec.emit("192.168.20.197 PORT 2323", 0) #self.SignalDataRec.emit("BYTES IN REC BUFFER - " + str(self.bytesAvailable)) def RecieveData(self): #self.CommandSocket.receiveDatagram(20) HEADER = QByteArray() HEADER.resize(2) if self.bytesAvailable < self.LimitBufferSize - self.MaxTransferUnit: #check that memory for packet available if self.BufferWrite.pos( ) < self.LimitBufferSize - self.MaxTransferUnit: (newData, sender, senderPort) = self.CommandSocket.readDatagram(20) #newData = self.CommandSocket.read(self.LimitBufferSize - self.bytesAvailable) #print(" NEW DATA - ",newData.toHex(),"to POS - ",self.BufferWrite.pos()) self.BufferWrite.write(newData) self.bytesAvailable += newData.size() print(self.Timer.restart()) #print("REC ",data) #print(" BUFFER - ",self.BufferWrite.data().toHex()) else: H1 = 0 H2 = 0 while self.CommandSocket.bytesAvailable() > 0: H1 = H2 H2 = self.SocketDataStream.readInt16() if H1 == 0xF1 and (H2 == 0xD1 or H2 == 0xD2 or H2 == 0xD3 or H2 == 0xC1): self.BufferWrite.seek(0) newData = self.CommandSocket.read( self.LimitBufferSize - self.bytesAvailable) self.WriteDataStream.writeInt16(H1) self.WriteDataStream.writeInt16(H2) print( "==============================================================" ) print("SEEK TO 0") print("NEW DATA - ", newData, "to POS - ", self.BufferWrite.pos() - 4) self.BufferWrite.write(newData) self.bytesAvailable += (4 + newData.size()) #print("BUFFER - ",self.NetworkDataArray.toHex()) break else: self.WriteDataStream.writeInt16(H2) self.bytesAvailable += 1 #self.SignalDataRec.emit("BYTES IN REC BUFFER - " + str(self.bytesAvailable)) if (self.bytesAvailable >= self.MinTransferUnit): self.SignalFrameDataAvailable.emit() def SendData(self): Req = ConnectCheckRequest() self.SendBuffer.clear() self.SendBuffer.resize(Req.MESSAGE_SIZE) WriteDataStream = QDataStream(self.SendBuffer, QIODevice.ReadWrite) WriteDataStream.setByteOrder(QDataStream.LittleEndian) Req >> WriteDataStream self.CommandSocket.write(self.SendBuffer) self.CommandSocket.waitForBytesWritten(20) self.SignalDataRec.emit("CHECK CONNECT - " + str(Req.Connect), 1) #self.CommandSocket.write(bytearray(b'TestMessage\r\n')) #print("WRITE BUFFER - ",self.SendBuffer.toHex()) #print("===============================================") def HandleErrorSocket(self): print("ErrorSocket")
class QCanvas(QLabel): def __init__(self, parent: QWidget, window: MainWindow): super().__init__(parent) self.pWindow = window self.strokeX = [] self.strokeY = [] self.strokeT = [] self.timing = QTime() self.timing.start() self.paused = 0 self.painter = QPainter() self.setStyleSheet("background-color: white;") """ EVENT: MOUSE CLICK/PRESS """ def mousePressEvent(self, event: QMouseEvent) -> None: self.timing.restart() self.strokeX.append(list()) self.strokeY.append(list()) self.strokeT.append(list()) self.strokeX[-1].append(event.x()) self.strokeY[-1].append(event.y()) self.strokeT[-1].append(self.paused) return super().mousePressEvent(event) """ EVENT: MOUSE MOVE WHILE PRESSED """ def mouseMoveEvent(self, event: QMouseEvent) -> None: if event.x() > 0 and event.y() > 0 and event.x() <= self.width() and event.y() <= self.height(): # IF DRAWING IS NOT JUST A MERE POINT... if len(self.strokeT[-1]) == 1: self.timing.restart() self.paused += 1 self.strokeX[-1].append(event.x()) self.strokeY[-1].append(event.y()) self.strokeT[-1].append(self.timing.elapsed() + self.paused) else: return return super().mouseMoveEvent(event) """ EVENT: MOUSE RELEASE """ def mouseReleaseEvent(self, event: QMouseEvent) -> None: # TO ABLE TO RECOGNIZE POINTS AS PART OF THE DRAWING... if len(self.strokeT[-1]) == 1: self.paused += 1 # OTHERWISE, CHECKPOINTS THE MILLISECONDS AS FOLLOWS. else: self.paused += (self.timing.elapsed() + 1) return super().mouseReleaseEvent(event) """ EVENT: UPDATE PAINT => Beware, every time paintEvent updates removes previous drawings. Therefore, store the data of previous drawing to prevent being erased. """ def paintEvent(self, event: QPaintEvent) -> None: pen = QPen() pen.setWidth(4) pen.setColor(Qt.color1) self.painter.begin(self) self.painter.setPen(pen) if len(self.strokeX) != 0: for stroke in range(len(self.strokeX)): if len(self.strokeX[stroke]) == 1: self.painter.drawPoint(self.strokeX[stroke][0], self.strokeY[stroke][0]) else: for index in range(len(self.strokeX[stroke]) - 1): self.painter.drawLine(self.strokeX[stroke][index], self.strokeY[stroke][index], self.strokeX[stroke][index+1], self.strokeY[stroke][index+1]) self.painter.end() self.update() return super().paintEvent(event) """ EVENT: UPON SHOWN """ def showEvent(self, event: QShowEvent) -> None: self.blankCanvas() return super().showEvent(event) """ METHOD: CREATE CANVAS """ def blankCanvas(self) -> None: margin = self.parentWidget().layout().margin() width = self.topLevelWidget().width() height = self.topLevelWidget().height() for index in range(self.parentWidget().layout().count()): if index != self.parentWidget().layout().indexOf(self): height -= (self.parentWidget().layout().itemAt(index).widget().height() + margin * 2) canvas = QBitmap(width - margin * 2, height) canvas.clear() self.setPixmap(canvas) self.update() """ METHOD: RESET CANVAS """ def resetCanvas(self) -> None: self.strokeX = [] self.strokeY = [] self.strokeT = [] self.paused = 0 self.blankCanvas() """ METHOD: UNDO CANVAS """ def undoCanvas(self) -> None: try: self.paused = self.strokeT[-1][0] self.strokeX.pop() self.strokeY.pop() self.strokeT.pop() except IndexError: print("The canvas is completely empty!") self.blankCanvas()