From 60380a253a7c4b862fad4d4111301044f28312b5 Mon Sep 17 00:00:00 2001 From: Blaine Date: Fri, 5 Jun 2020 12:14:26 +0530 Subject: json file format + qsettings --- src/main/python/main.py | 46 +++++++++++++++++++++++++++---------- src/main/python/utils/app.py | 3 +++ src/main/python/utils/canvas.py | 14 +++++------ src/main/python/utils/fileWindow.py | 26 ++++++++++----------- 4 files changed, 57 insertions(+), 32 deletions(-) (limited to 'src/main/python') diff --git a/src/main/python/main.py b/src/main/python/main.py index 3ebb2b9..025961b 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -1,8 +1,9 @@ import pickle +import json import sys from fbs_runtime.application_context.PyQt5 import ApplicationContext -from PyQt5.QtCore import QObject, Qt, pyqtSignal +from PyQt5.QtCore import QObject, Qt, pyqtSignal, QSize, QPoint from PyQt5.QtGui import QBrush, QColor, QImage, QPainter, QPalette, QPen from PyQt5.QtWidgets import (QComboBox, QFileDialog, QFormLayout, QVBoxLayout, QHBoxLayout, QLabel, QMainWindow, QMenu, @@ -13,7 +14,7 @@ from utils.fileWindow import fileWindow from utils.data import ppiList, sheetDimensionList from utils import dialogs from utils.toolbar import toolbar -from utils.app import app +from utils.app import app, settings import shapes @@ -58,7 +59,8 @@ class appWindow(QMainWindow): #declare main window layout self.setCentralWidget(self.mdi) - self.resize(1280, 720) #set collapse dim + # self.resize(1280, 720) #set collapse dim + self.readSettings() self.mdi.subWindowActivated.connect(self.tabSwitched) def updateMenuBar(self): @@ -91,7 +93,7 @@ class appWindow(QMainWindow): self.mdi.addSubWindow(project) if not project.tabList: # important when unpickling a file instead project.newDiagram() #create a new tab in the new file - project.resizeHandler() + # project.resizeHandler() project.fileCloseEvent.connect(self.fileClosed) #closed file signal to switch to sub window view project.tabChangeEvent.connect(self.updateMenuBar) if self.count > 1: #switch to tab view if needed @@ -103,12 +105,15 @@ class appWindow(QMainWindow): name = QFileDialog.getOpenFileNames(self, 'Open File(s)', '', 'Process Flow Diagram (*pfd)') if name: for files in name[0]: - with open(files,'rb') as file: - project = pickle.load(file) + with open(files,'r') as file: + projectData = json.load(file) + project = fileWindow(self.mdi) self.mdi.addSubWindow(project) - project.show() + project.__setstate__(projectData) project.resizeHandler() - project.fileCloseEvent.connect(self.fileClosed) + project.fileCloseEvent.connect(self.fileClosed) + project.tabChangeEvent.connect(self.updateMenuBar) + project.show() if self.count > 1: # self.tabSpace.setVisible(True) self.mdi.setViewMode(QMdiArea.TabbedView) @@ -133,7 +138,7 @@ class appWindow(QMainWindow): def tabSwitched(self, window): #handle window switched edge case - if window: + if window and window.tabCount: window.resizeHandler() def resizeEvent(self, event): @@ -148,13 +153,30 @@ class appWindow(QMainWindow): if len(self.activeFiles) and not dialogs.saveEvent(self): event.ignore() else: - event.accept() + event.accept() + self.writeSettings() def fileClosed(self, index): #checks if the file tab menu needs to be removed if self.count <= 2 : self.mdi.setViewMode(QMdiArea.SubWindowView) - + + def writeSettings(self): + settings.beginGroup("MainWindow") + settings.setValue("maximized", self.isMaximized()) + if not self.isMaximized(): + settings.setValue("size", self.size()) + settings.setValue("pos", self.pos()) + settings.endGroup() + + def readSettings(self): + settings.beginGroup("MainWindow") + self.resize(settings.value("size", QSize(1280, 720))) + self.move(settings.value("pos", QPoint(320, 124))) + if settings.value("maximized", False, type=bool): + self.showMaximized() + settings.endGroup() + @property def activeFiles(self): return [i for i in self.mdi.subWindowList() if i.tabCount] @@ -166,7 +188,7 @@ class appWindow(QMainWindow): @property def activeScene(self): return self.mdi.currentSubWindow().tabber.currentWidget() - + #Key input handler def keyPressEvent(self, event): #overload key press event for custom keyboard shortcuts diff --git a/src/main/python/utils/app.py b/src/main/python/utils/app.py index 4540a43..4ee11c3 100644 --- a/src/main/python/utils/app.py +++ b/src/main/python/utils/app.py @@ -3,7 +3,10 @@ Declare fbs application so that it can be imported in other modules. """ from fbs_runtime.application_context.PyQt5 import ApplicationContext +from PyQt5.QtCore import QSettings + app = ApplicationContext() +settings = QSettings(QSettings.IniFormat, QSettings.UserScope ,"FOSSEE", "Chemical-PFD") def fileImporter(file): # Helper function to fetch files from src/main/resources diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 2332087..5da4487 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -15,7 +15,7 @@ class canvas(QWidget): for context menu and dialogs. """ - def __init__(self, parent=None, size= 'A4', ppi= '72'): + def __init__(self, parent=None, size= 'A4', ppi= '72' , parentMdiArea = None, parentFileWindow = None): super(canvas, self).__init__(parent) #Store values for the canvas dimensions for ease of access, these are here just to be @@ -38,11 +38,11 @@ class canvas(QWidget): self.setLayout(self.layout) #set initial paper size for the scene - self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) - - #set pointers to necessary parents for ease of reference - self.parentMdiArea = self.parent().parentWidget().parentWidget().parentWidget().parentWidget() - self.parentFileWindow = self.parent().parentWidget().parentWidget() + self.painter.setSceneRect(0, 0, *paperSizes[self._canvasSize][self._ppi]) + # self.parentMdiArea = self.parent().parentWidget().parentWidget().parentWidget().parentWidget() + # self.parentFileWindow = self.parent().parentWidget().parentWidget() + self.parentMdiArea = parentMdiArea + self.parentFileWindow = parentFileWindow def resizeView(self, w, h): #helper function to resize canvas @@ -95,6 +95,7 @@ class canvas(QWidget): def dimensions(self): #returns the dimension of the current scene return self.painter.sceneRect().width(), self.painter.sceneRect().height() + @property def items(self): # generator to filter out certain items @@ -132,7 +133,6 @@ class canvas(QWidget): } def __setstate__(self, dict): - self.__init__() self._ppi = dict['ppi'] self._canvasSize = dict['canvasSize'] self.setObjectName(dict['ObjectName']) diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index ebe509b..3cf0e8c 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -1,4 +1,5 @@ import pickle +import json from PyQt5.QtCore import Qt, pyqtSignal, QPoint from PyQt5.QtGui import QIcon @@ -24,8 +25,8 @@ class fileWindow(QMdiSubWindow): def __init__(self, parent = None, title = 'New Project', size = 'A4', ppi = '72'): super(fileWindow, self).__init__(parent) self._sideViewTab = None - self.index = None - + self.index = None + self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) #Uses a custom QTabWidget that houses a custom new Tab Button, used to house the seperate # diagrams inside a file @@ -210,19 +211,20 @@ class fileWindow(QMdiSubWindow): self.tabber.widget(currentIndex).deleteLater() self.tabber.removeTab(currentIndex) - def newDiagram(self): + def newDiagram(self, objectName = "New"): # helper function to add a new tab on pressing new tab button, using the add tab method on QTabWidget - diagram = canvas(self.tabber) - diagram.setObjectName("New") - index = self.tabber.addTab(diagram, "New") + diagram = canvas(self.tabber, parentMdiArea = self.mdiArea(), parentFileWindow = self) + diagram.setObjectName(objectName) + index = self.tabber.addTab(diagram, objectName) self.tabber.setCurrentIndex(index) + return diagram def saveProject(self, name = None): # called by dialog.saveEvent, saves the current file name = QFileDialog.getSaveFileName(self, 'Save File', f'New Diagram', 'Process Flow Diagram (*.pfd)') if not name else name if name[0]: - with open(name[0],'wb') as file: - pickle.dump(self, file) + with open(name[0],'w') as file: + json.dump(self.__getstate__(), file, indent=4) return True else: return False @@ -242,14 +244,12 @@ class fileWindow(QMdiSubWindow): return { "_classname_": self.__class__.__name__, "ObjectName": self.objectName(), - "ppi": self._ppi, - "canvasSize": self._canvasSize, "tabs": [i.__getstate__() for i in self.tabList] } def __setstate__(self, dict): - self.__init__(title = dict['ObjectName']) + self.setObjectName = dict['ObjectName'] + self.setWindowTitle = dict['ObjectName'] for i in dict['tabs']: - diagram = canvas(self.tabber, size = dict['canvasSize'], ppi = dict['ppi'], fileWindow = self) + diagram = self.newDiagram(i['ObjectName']) diagram.__setstate__(i) - self.tabber.addTab(diagram, i['ObjectName']) -- cgit From 4eaa5eacee5778f290577eb63cbae163a98d9d53 Mon Sep 17 00:00:00 2001 From: Blaine Date: Mon, 8 Jun 2020 19:36:25 +0530 Subject: serialization for scene items --- src/main/python/main.py | 5 ++--- src/main/python/shapes/line.py | 16 +++++++++++++++- src/main/python/utils/canvas.py | 35 ++++++++++++++++++++++++++--------- src/main/python/utils/fileWindow.py | 1 - 4 files changed, 43 insertions(+), 14 deletions(-) (limited to 'src/main/python') diff --git a/src/main/python/main.py b/src/main/python/main.py index 025961b..72eb7f8 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -1,4 +1,3 @@ -import pickle import json import sys @@ -60,8 +59,8 @@ class appWindow(QMainWindow): #declare main window layout self.setCentralWidget(self.mdi) # self.resize(1280, 720) #set collapse dim - self.readSettings() self.mdi.subWindowActivated.connect(self.tabSwitched) + self.readSettings() def updateMenuBar(self): # used to update menu bar undo-redo buttons to current scene @@ -154,7 +153,7 @@ class appWindow(QMainWindow): event.ignore() else: event.accept() - self.writeSettings() + self.writeSettings() def fileClosed(self, index): #checks if the file tab menu needs to be removed diff --git a/src/main/python/shapes/line.py b/src/main/python/shapes/line.py index dc0a09c..b798dff 100644 --- a/src/main/python/shapes/line.py +++ b/src/main/python/shapes/line.py @@ -893,4 +893,18 @@ class Line(QGraphicsPathItem): addLableAction = contextMenu.addAction("add Label") action = contextMenu.exec_(event.screenPos()) if action == addLableAction: - self.label.append(LineLabel(event.scenePos(), self)) \ No newline at end of file + self.label.append(LineLabel(event.scenePos(), self)) + def setPenStyle(self, style): + """change current pen style for line""" + self.penStyle = style + + def __getstate__(self): + return { + "_classname_": self.__class__.__name__, + "startPoint": (self.startPoint.x(), self.startPoint.y()), + "endPoint": (self.endPoint.x(), self.endPoint.y()), + "points": [(point.x(), point.y()) for point in self.points] + } + + def __setstate__(self, dict): + self.points = [QPointF(x, y) for x, y in dict["points"]] diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 5da4487..dee0745 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -1,6 +1,6 @@ -import pickle +import json -from PyQt5.QtCore import Qt +from PyQt5.QtCore import Qt, QPointF from PyQt5.QtGui import QBrush, QPalette from PyQt5.QtWidgets import (QFileDialog, QApplication, QHBoxLayout, QMenu, QTabWidget, QWidget, QSpacerItem, QStyle) @@ -9,6 +9,8 @@ from . import dialogs from .graphics import customView, customScene from .data import paperSizes, ppiList, sheetDimensionList +import shapes + class canvas(QWidget): """ Defines the work area for a single sheet. Contains a QGraphicScene along with necessary properties @@ -27,7 +29,7 @@ class canvas(QWidget): # when we will draw items on this, this might be changed if QGraphicScene is subclassed. #set layout and background color - self.painter = customScene() + self.painter = customScene() self.painter.setBackgroundBrush(QBrush(Qt.white)) #set white background self.view = customView(self.painter, self) #create a viewport for the canvas board @@ -39,8 +41,6 @@ class canvas(QWidget): #set initial paper size for the scene self.painter.setSceneRect(0, 0, *paperSizes[self._canvasSize][self._ppi]) - # self.parentMdiArea = self.parent().parentWidget().parentWidget().parentWidget().parentWidget() - # self.parentFileWindow = self.parent().parentWidget().parentWidget() self.parentMdiArea = parentMdiArea self.parentFileWindow = parentFileWindow @@ -129,16 +129,33 @@ class canvas(QWidget): "ppi": self._ppi, "canvasSize": self._canvasSize, "ObjectName": self.objectName(), - "items": [i.__getState__() for i in self.painter.items()] + "symbols": [i.__getstate__() for i in self.painter.items() if isinstance(i, shapes.NodeItem)], + "lines": [i.__getstate__() for i in self.painter.items() if isinstance(i, shapes.Line)], + # "lineLabels": [i.__getstate__() for i in self.painter.items() if isinstance(i, shapes.LineLabel)], + # "itemLabels": [i.__getstate__() for i in self.painter.items() if isinstance(i, shapes.itemLabel)] } def __setstate__(self, dict): self._ppi = dict['ppi'] self._canvasSize = dict['canvasSize'] self.setObjectName(dict['ObjectName']) - for item in dict['items']: - graphic = getattr(graphics, dict['_classname_']) - graphic.__setstate__(item) + + for item in dict['symbols']: + graphic = getattr(shapes, item['_classname_'])() + graphic.__setstate__(dict = item) self.painter.addItem(graphic) + graphic.setPos(*item['pos']) + + for item in dict['lines']: + line = shapes.Line(QPointF(*item['startPoint']), QPointF(*item['endPoint'])) + line.__setstate__(dict = item) + self.painter.addItem(line) + + self.painter.advance() + + # for item in dict['lineLabels']: + # pass + # for item in dict['itemLabels']: + # pass \ No newline at end of file diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index 3cf0e8c..6ad4477 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -1,4 +1,3 @@ -import pickle import json from PyQt5.QtCore import Qt, pyqtSignal, QPoint -- cgit