Mercurial > lcfOS
diff python/other/diagrameditor.py @ 390:b77f3290ac79
Added diagram editor tests
author | Windel Bouwman |
---|---|
date | Fri, 16 May 2014 10:12:16 +0200 |
parents | 7b38782ed496 |
children | bb4289c84907 |
line wrap: on
line diff
--- a/python/other/diagrameditor.py Fri May 02 14:51:46 2014 +0200 +++ b/python/other/diagrameditor.py Fri May 16 10:12:16 2014 +0200 @@ -1,11 +1,16 @@ #!/usr/bin/python -from PyQt4.QtGui import * -from PyQt4.QtCore import * -import sys, json, base64 +import sys +import json +import base64 +import os + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'ide')) + +from qtwrapper import QtGui, QtCore, QtWidgets, pyqtSignal, get_icon +from qtwrapper import abspath, Qt from diagramitems import Connection, ResizeSelectionHandle, Block, DiagramScene, CodeBlock -from icons import newicon, saveicon, loadicon import diagramitems """ @@ -15,10 +20,13 @@ run with python 3.x as: $ python [thisfile.py] """ + + def indent(lines): return [' ' + line for line in lines] -class ParameterDialog(QDialog): + +class ParameterDialog(QtWidgets.QDialog): def __init__(self, block, parent = None): super(ParameterDialog, self).__init__(parent) self.block = block @@ -36,24 +44,30 @@ self.block.code = self.codeEdit.toPlainText() self.close() -class EditorGraphicsView(QGraphicsView): + +class EditorGraphicsView(QtWidgets.QGraphicsView): def __init__(self, parent=None): - QGraphicsView.__init__(self, parent) - self.setDragMode(QGraphicsView.RubberBandDrag) - self.delShort = QShortcut(QKeySequence.Delete, self) + super().__init__(parent) + self.setObjectName('Editor') + self.setDragMode(QtWidgets.QGraphicsView.RubberBandDrag) + self.delShort = QtWidgets.QShortcut(QtGui.QKeySequence.Delete, self) self._model = None - self.treeView = QTreeView() + self.treeView = QtWidgets.QTreeView() self.treeView.clicked.connect(self.itemActivated) + def itemActivated(self, idx): b = idx.internalPointer() s = b.scene() s.clearSelection() b.setSelected(True) + def setDiagram(self, d): self.setScene(d) self.delShort.activated.connect(d.deleteItems) + def getModel(self): return self._model + def setModel(self, m): self._model = m if m: @@ -70,15 +84,19 @@ with open(self.model.filename, 'w') as f: f.write(json.dumps(self.model.Dict, indent=2)) def load(self): - filename = QFileDialog.getOpenFileName(self) - if filename: - self.model = loadModel(filename) + filename = QtWidgets.QFileDialog.getOpenFileName(self) + if filename: + self.model = loadModel(filename) + def newModel(self): - self.model = ModelHierarchyModel() + print('NEW') + self.model = ModelHierarchyModel() + def goUp(self): if hasattr(self.diagram, 'containingBlock'): self.diagram = self.diagram.containingBlock.scene() self.zoomAll() + def showCode(self): if self.model: c = self.model.gencode() @@ -101,10 +119,12 @@ exec(codeview.toPlainText(), globs) runButton.clicked.connect(runIt) d.exec_() + def zoomAll(self): """ zoom to fit all items """ rect = self.diagram.itemsBoundingRect() self.fitInView(rect, Qt.KeepAspectRatio) + def wheelEvent(self, event): pos = event.pos() posbefore = self.mapToScene(pos) @@ -112,11 +132,15 @@ sx = (100.0 + degrees) / 100.0 self.scale(sx, sx) event.accept() + def dragEnterEvent(self, event): - if event.mimeData().hasFormat('component/name'): - event.accept() + if event.mimeData().hasFormat('component/name'): + event.accept() + def dragMoveEvent(self, event): - if event.mimeData().hasFormat('component/name'): event.accept() + if event.mimeData().hasFormat('component/name'): + event.accept() + def dropEvent(self, event): if event.mimeData().hasFormat('component/name'): name = bytes(event.mimeData().data('component/name')).decode() @@ -132,29 +156,39 @@ b.setPos(pos) s.addItem(b) -class LibraryModel(QStandardItemModel): - mimeTypes = lambda self: ['component/name'] - def mimeData(self, idxs): - mimedata = QMimeData() - for idx in idxs: - if idx.isValid(): - txt = self.data(idx, Qt.DisplayRole) - mimedata.setData('component/name', txt) - return mimedata + +class LibraryModel(QtGui.QStandardItemModel): + def __init__(self, parent): + super().__init__(parent) + self.setObjectName('Library') -class ModelHierarchyModel(QAbstractItemModel): + mimeTypes = lambda self: ['component/name'] + def mimeData(self, idxs): + mimedata = QtCore.QMimeData() + for idx in idxs: + if idx.isValid(): + txt = self.data(idx, Qt.DisplayRole) + mimedata.setData('component/name', txt) + return mimedata + + +class ModelHierarchyModel(QtCore.QAbstractItemModel): def __init__(self): super(ModelHierarchyModel, self).__init__() self.rootDiagram = DiagramScene() self.rootDiagram.structureChanged.connect(self.handlechange) self.filename = None + def handlechange(self): self.modelReset.emit() + def setDict(self, d): self.rootDiagram.Dict = d self.modelReset.emit() + def getDict(self): return self.rootDiagram.Dict + Dict = property(getDict, setDict) def gencode(self): c = ['def topLevel():'] @@ -163,6 +197,7 @@ c.append('topLevel()') c.append('print("Done")') return c + def index(self, row, column, parent=None): if parent.isValid(): parent = parent.internalPointer().subModel @@ -174,6 +209,7 @@ # TODO: solve this in a better way. block.index = self.createIndex(row, column, block) return block.index + def parent(self, index): if index.isValid(): block = index.internalPointer() @@ -184,6 +220,7 @@ outerBlock = block.scene().containingBlock return outerBlock.index print('parent: No valid index') + def data(self, index, role): if index.isValid() and role == Qt.DisplayRole: b = index.internalPointer() @@ -191,6 +228,7 @@ return b.name elif index.column() == 1: return str(type(b)) + def headerData(self, section, orientation, role): if orientation == Qt.Horizontal and role == Qt.DisplayRole: if section == 0: @@ -199,6 +237,7 @@ return "Type" else: return "x" + def rowCount(self, parent): if parent.column() > 0: return 0 @@ -210,32 +249,37 @@ return 0 else: return len(self.rootDiagram.blocks) + def columnCount(self, parent): return 2 -class LibraryWidget(QListView): - def __init__(self): - super(LibraryWidget, self).__init__(None) + +class LibraryWidget(QtWidgets.QListView): + def __init__(self): + super().__init__() + self.setObjectName('LibraryWidget') self.libraryModel = LibraryModel(self) self.libraryModel.setColumnCount(1) # Create an icon with an icon: - pixmap = QPixmap(60, 60) + pixmap = QtGui.QPixmap(60, 60) pixmap.fill() - painter = QPainter(pixmap) + painter = QtGui.QPainter(pixmap) painter.fillRect(10, 10, 40, 40, Qt.blue) painter.setBrush(Qt.yellow) painter.drawEllipse(20, 20, 20, 20) painter.end() # Fill library: for name in ['CodeBlock:codeBlock', 'DiagramBlock:submod', 'Block:blk']: - self.libraryModel.appendRow(QStandardItem(QIcon(pixmap), name)) + self.libraryModel.appendRow(QtGui.QStandardItem(QtGui.QIcon(pixmap), name)) self.setModel(self.libraryModel) self.setViewMode(self.IconMode) self.setDragDropMode(self.DragOnly) + def warning(txt): QMessageBox.warning(None, "Warning", txt) + def loadModel(filename): try: m = ModelHierarchyModel() @@ -250,8 +294,9 @@ except FileNotFoundError: warning('File [{0}] not found'.format(filename)) -class Main(QMainWindow): - def __init__(self): + +class Main(QtWidgets.QMainWindow): + def __init__(self): super(Main, self).__init__(None) self.editor = EditorGraphicsView() self.setCentralWidget(self.editor) @@ -264,30 +309,32 @@ toolbar = self.addToolBar('Tools') toolbar.setObjectName('Tools') def act(name, shortcut, callback, icon=None): - a = QAction(icon, name, self) if icon else QAction(name, self) + a = QtWidgets.QAction(icon, name, self) if icon else QtWidgets.QAction(name, self) a.setShortcuts(shortcut) a.triggered.connect(callback) toolbar.addAction(a) - act('New', QKeySequence.New, self.editor.newModel, buildIcon(newicon)) - act('Save', QKeySequence.Save, self.editor.save, buildIcon(saveicon)) - act('Load', QKeySequence.Open, self.editor.load, buildIcon(loadicon)) - act('Full screen', QKeySequence("F11"), self.toggleFullScreen) - act('Fit in view', QKeySequence("F8"), self.editor.zoomAll) - act('Go up', QKeySequence(Qt.Key_Up), self.editor.goUp) - act('Model code', QKeySequence("F7"), self.editor.showCode) + act('New', QtGui.QKeySequence.New, self.editor.newModel) + act('Save', QtGui.QKeySequence.Save, self.editor.save) + act('Load', QtGui.QKeySequence.Open, self.editor.load) + act('Full screen', QtGui.QKeySequence("F11"), self.toggleFullScreen) + act('Fit in view', QtGui.QKeySequence("F8"), self.editor.zoomAll) + act('Go up', QtGui.QKeySequence(Qt.Key_Up), self.editor.goUp) + act('Model code', QtGui.QKeySequence("F7"), self.editor.showCode) def addDock(name, widget): - dock = QDockWidget(name, self) + dock = QtWidgets.QDockWidget(name, self) dock.setObjectName(name) dock.setWidget(widget) self.addDockWidget(Qt.LeftDockWidgetArea, dock) addDock('Library', LibraryWidget()) addDock('Model tree', self.editor.treeView) - self.settings = QSettings('windelsoft', 'diagrameditor') + self.settings = QtCore.QSettings('windelsoft', 'diagrameditor') self.loadSettings() - def toggleFullScreen(self): - self.setWindowState(self.windowState() ^ Qt.WindowFullScreen) - self.editor.zoomAll() - def loadSettings(self): + + def toggleFullScreen(self): + self.setWindowState(self.windowState() ^ Qt.WindowFullScreen) + self.editor.zoomAll() + + def loadSettings(self): if self.settings.contains('mainwindowstate'): self.restoreState(self.settings.value('mainwindowstate')) if self.settings.contains('mainwindowgeometry'): @@ -295,7 +342,8 @@ if self.settings.contains('openedmodel'): modelfile = self.settings.value('openedmodel') self.editor.model = loadModel(modelfile) - def closeEvent(self, ev): + + def closeEvent(self, ev): self.settings.setValue('mainwindowstate', self.saveState()) self.settings.setValue('mainwindowgeometry', self.saveGeometry()) if self.editor.model and self.editor.model.filename: @@ -309,7 +357,7 @@ if sys.version_info.major != 3: print('Please use python 3.x') sys.exit(1) - app = QApplication(sys.argv) + app = QtWidgets.QApplication(sys.argv) main = Main() main.show() app.exec_()