summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlaine2020-06-20 14:43:57 +0530
committerBlaine2020-06-20 14:43:57 +0530
commitf8519766d7f7fc70180411f912ed8ca15abb6a95 (patch)
tree97eb7e5570b43f3fc10628d37360351330e16bf3
parent7ff2d30a1c16216f3bfaebc8f71924d6a6f8ec8d (diff)
downloadChemical-PFD-f8519766d7f7fc70180411f912ed8ca15abb6a95.tar.gz
Chemical-PFD-f8519766d7f7fc70180411f912ed8ca15abb6a95.tar.bz2
Chemical-PFD-f8519766d7f7fc70180411f912ed8ca15abb6a95.zip
refactor and comment code
-rw-r--r--src/main/python/main.py63
-rw-r--r--src/main/python/shapes/shapes.py3
-rw-r--r--src/main/python/utils/app.py18
-rw-r--r--src/main/python/utils/canvas.py25
-rw-r--r--src/main/python/utils/custom.py64
-rw-r--r--src/main/python/utils/dialogs.py1
-rw-r--r--src/main/python/utils/fileWindow.py13
-rw-r--r--src/main/python/utils/graphics.py8
-rw-r--r--src/main/python/utils/layout.py16
-rw-r--r--src/main/python/utils/streamTable.py78
-rw-r--r--src/main/python/utils/tabs.py3
-rw-r--r--src/main/python/utils/toolbar.py2
-rw-r--r--src/main/python/utils/undo.py1
13 files changed, 192 insertions, 103 deletions
diff --git a/src/main/python/main.py b/src/main/python/main.py
index db938b5..35c95c3 100644
--- a/src/main/python/main.py
+++ b/src/main/python/main.py
@@ -25,8 +25,30 @@ class appWindow(QMainWindow):
super(appWindow, self).__init__(parent)
#create the menu bar
+ self.createMenuBar()
+
+ self.mdi = QMdiArea(self) #create area for files to be displayed
+ self.mdi.setObjectName('mdi area')
+
+ #create toolbar and add the toolbar plus mdi to layout
+ self.createToolbar()
+
+ #set flags so that window doesnt look weird
+ self.mdi.setOption(QMdiArea.DontMaximizeSubWindowOnActivation, True)
+ self.mdi.setTabsClosable(True)
+ self.mdi.setTabsMovable(True)
+ self.mdi.setDocumentMode(False)
+
+ #declare main window layout
+ self.setCentralWidget(self.mdi)
+ # self.resize(1280, 720) #set collapse dim
+ self.mdi.subWindowActivated.connect(self.tabSwitched)
+ self.readSettings()
+
+ def createMenuBar(self):
+ # Fetches a reference to the menu bar in the main window, and adds actions to it.
+
titleMenu = self.menuBar() #fetch reference to current menu bar
- # self.mainWidget.setObjectName("Main Widget")
self.menuFile = titleMenu.addMenu('File') #File Menu
newAction = self.menuFile.addAction("New", self.newProject)
@@ -54,25 +76,7 @@ class appWindow(QMainWindow):
imageAction.setShortcut(QKeySequence("Ctrl+P"))
reportAction.setShortcut(QKeySequence("Ctrl+R"))
-
- self.mdi = QMdiArea(self) #create area for files to be displayed
- self.mdi.setObjectName('mdi area')
-
- #create toolbar and add the toolbar plus mdi to layout
- self.createToolbar()
-
- #set flags so that window doesnt look weird
- self.mdi.setOption(QMdiArea.DontMaximizeSubWindowOnActivation, True)
- self.mdi.setTabsClosable(True)
- self.mdi.setTabsMovable(True)
- self.mdi.setDocumentMode(False)
-
- #declare main window layout
- self.setCentralWidget(self.mdi)
- # self.resize(1280, 720) #set collapse dim
- self.mdi.subWindowActivated.connect(self.tabSwitched)
- self.readSettings()
-
+
def createToolbar(self):
#place holder for toolbar with fixed width, layout may change
self.toolbar = toolbar(self)
@@ -83,16 +87,16 @@ class appWindow(QMainWindow):
self.toolbar.populateToolbar()
def toolButtonClicked(self, object):
+ # To add the corresponding symbol for the clicked button to active scene.
if self.mdi.currentSubWindow():
currentDiagram = self.mdi.currentSubWindow().tabber.currentWidget().painter
if currentDiagram:
graphic = getattr(shapes, object['object'])(*map(lambda x: int(x) if x.isdigit() else x, object['args']))
- # graphic.setPen(QPen(Qt.black, 2))
- # graphic.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable)
- graphic.setPos(20, 20)
+ graphic.setPos(50, 50)
currentDiagram.addItemPlus(graphic)
def addSymbolWindow(self):
+ # Opens the add symbol window when requested
from utils.custom import ShapeDialog
ShapeDialog(self).exec()
@@ -103,7 +107,6 @@ 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.fileCloseEvent.connect(self.fileClosed) #closed file signal to switch to sub window view
if self.count > 1: #switch to tab view if needed
self.mdi.setViewMode(QMdiArea.TabbedView)
@@ -118,6 +121,7 @@ class appWindow(QMainWindow):
projectData = load(file)
project = FileWindow(self.mdi)
self.mdi.addSubWindow(project)
+ #create blank window and set its state
project.__setstate__(projectData)
project.resizeHandler()
project.fileCloseEvent.connect(self.fileClosed)
@@ -127,7 +131,7 @@ class appWindow(QMainWindow):
self.mdi.setViewMode(QMdiArea.TabbedView)
def saveProject(self):
- #pickle all files in mdi area
+ #serialize all files in mdi area
for j, i in enumerate(self.activeFiles): #get list of all windows with atleast one tab
if i.tabCount:
name = QFileDialog.getSaveFileName(self, 'Save File', f'New Diagram {j}', 'Process Flow Diagram (*.pfd)')
@@ -170,6 +174,7 @@ class appWindow(QMainWindow):
self.mdi.setViewMode(QMdiArea.SubWindowView)
def writeSettings(self):
+ # write window state on window close
settings.beginGroup("MainWindow")
settings.setValue("maximized", self.isMaximized())
if not self.isMaximized():
@@ -178,6 +183,7 @@ class appWindow(QMainWindow):
settings.endGroup()
def readSettings(self):
+ # read window state when app launches
settings.beginGroup("MainWindow")
self.resize(settings.value("size", QSize(1280, 720)))
self.move(settings.value("pos", QPoint(320, 124)))
@@ -185,6 +191,7 @@ class appWindow(QMainWindow):
self.showMaximized()
settings.endGroup()
+ #useful one liner properties for getting data
@property
def activeFiles(self):
return [i for i in self.mdi.subWindowList() if i.tabCount]
@@ -219,11 +226,9 @@ class appWindow(QMainWindow):
if self.mdi.activeSubWindow() and self.mdi.activeSubWindow().tabber.currentWidget():
for item in self.mdi.activeSubWindow().tabber.currentWidget().painter.selectedItems():
item.rotation += 1
-
-
-
+
if __name__ == '__main__': # 1. Instantiate ApplicationContext
main = appWindow()
main.show()
- exit_code = app.app.exec_() # 2. Invoke appctxt.app.exec_()
+ exit_code = app.app.exec_() # 2. Invoke app.app.exec_()
sys.exit(exit_code)
diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py
index ca6490c..5876f6e 100644
--- a/src/main/python/shapes/shapes.py
+++ b/src/main/python/shapes/shapes.py
@@ -12,6 +12,7 @@ from PyQt5.QtWidgets import (QGraphicsColorizeEffect, QGraphicsEllipseItem,
from .line import Line, findIndex
from utils.app import fileImporter
+# enum for all directions for line grip items
directionsEnum = [
"top",
"right",
@@ -19,6 +20,7 @@ directionsEnum = [
"left"
]
+# orientation enum for size grip items
orientationEnum = [
Qt.Horizontal,
Qt.Vertical
@@ -469,6 +471,7 @@ class NodeItem(QGraphicsSvgItem):
return self.flipState[1]
def updateTransformation(self):
+ # update transformation on flipstate or rotation change
transform = QTransform()
h = -1 if self.flipH else 1
w = -1 if self.flipV else 1
diff --git a/src/main/python/utils/app.py b/src/main/python/utils/app.py
index 275ef7e..39c3674 100644
--- a/src/main/python/utils/app.py
+++ b/src/main/python/utils/app.py
@@ -1,5 +1,5 @@
"""
-Declare fbs application so that it can be imported in other modules.
+Declare fbs application and various contextual variables so that it can be imported in other modules.
"""
from fbs_runtime.application_context.PyQt5 import ApplicationContext
@@ -9,7 +9,7 @@ from PyQt5.QtWidgets import QWidget
from json import JSONEncoder, dumps, loads, dump, load
from os.path import join
-from resources import resources
+from resources import resources #application resources defined in resources.qrc
app = ApplicationContext()
settings = QSettings(QSettings.IniFormat, QSettings.UserScope ,"FOSSEE", "Chemical-PFD")
@@ -19,11 +19,14 @@ def fileImporter(*file):
# Helper function to fetch files from src/main/resources
return app.get_resource(join(*file))
+#set application stylesheet
with open(fileImporter("app.qss"), "r") as stylesheet:
app.app.setStyleSheet(stylesheet.read())
class JSON_Encoder:
-
+ """
+ Defines serialization methods for differnt data types for json module
+ """
def _encode(obj):
if isinstance(obj, dict):
## We'll need to iterate not just the value that default() usually gets passed
@@ -50,7 +53,9 @@ class JSON_Encoder:
return obj
class JSON_Typer(JSONEncoder):
-
+ """
+ derived class for redirecting encode calls
+ """
def default(self, o):
return o.__getstate__()
@@ -60,7 +65,4 @@ class JSON_Typer(JSONEncoder):
def encode(self, obj):
return super(JSON_Typer, self).encode(self._encode(obj))
-
-importer = pyqtProperty(str, fileImporter)
-
-memMap = {} \ No newline at end of file
+memMap = {} #memory map for id references for loading projects \ No newline at end of file
diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py
index 8608f7b..68b0902 100644
--- a/src/main/python/utils/canvas.py
+++ b/src/main/python/utils/canvas.py
@@ -42,6 +42,9 @@ class canvas(CustomView):
self.customContextMenuRequested.connect(self.sideViewContextMenu)
def addStreamTable(self, pos=QPointF(0, 0), table=None):
+ """
+ build stream table at pos with table, if table is not passed, builds a blank table
+ """
self.streamTable = table if table else streamTable(self.labelItems, canvas=self)
self.streamTableRect = moveRect()
@@ -53,10 +56,16 @@ class canvas(CustomView):
self.streamTableRect.setPos(pos)
def updateStreamTable(self, item):
+ """
+ updates stream table with any new line labels added
+ """
if self.streamTable:
self.streamTable.model.insertColumn(item = item)
def sideViewContextMenu(self, pos):
+ """
+ shows the context menu for the side view
+ """
self.parentFileWindow.sideViewContextMenu(self.mapTo(self.parentFileWindow, pos))
def resizeView(self, w, h):
@@ -69,11 +78,6 @@ class canvas(CustomView):
frameWidth = self.frameWidth()
#update view size
self.setSceneRect(0, 0, width - frameWidth*2, height)
-
- def resizeEvent(self, event):
- #overloaded function to also view size on window update
- # self.adjustView()
- pass
def setCanvasSize(self, size):
"""
@@ -152,6 +156,7 @@ class canvas(CustomView):
self.landscape = dict['landscape']
self.setObjectName(dict['ObjectName'])
+ #load symbols from the file, while building the memory map as well.
for item in dict['symbols']:
graphic = getattr(shapes, item['_classname_'])()
graphic.__setstate__(dict = item)
@@ -168,6 +173,7 @@ class canvas(CustomView):
graphic.rotation = item['rotation']
graphic.flipH, graphic.flipV = item['flipstate']
+ #load lines from the file, while using and building the memory map.
for item in dict['lines']:
line = shapes.Line(QPointF(*item['startPoint']), QPointF(*item['endPoint']))
memMap[item['id']] = line
@@ -192,14 +198,11 @@ class canvas(CustomView):
line.updateLine()
line.addGrabber()
+ # add streamtable if it existed in the scene.
if dict['streamTable']:
table = streamTable(self.labelItems, self)
self.addStreamTable(QPointF(*dict['streamTable'][1]), table)
table.__setstate__(dict['streamTable'][0])
- memMap.clear()
- self.painter.advance()
-
-
-
- \ No newline at end of file
+ memMap.clear() #clear out memory map as we now have no use for it. Hopefully garbage collected
+ self.painter.advance() #request collision detection \ No newline at end of file
diff --git a/src/main/python/utils/custom.py b/src/main/python/utils/custom.py
index 7e6b197..fedecdb 100644
--- a/src/main/python/utils/custom.py
+++ b/src/main/python/utils/custom.py
@@ -1,3 +1,6 @@
+"""
+Holds the custom window to generate new symbols, can be called while running or throught the build interface.
+"""
from PyQt5.QtCore import QRectF, Qt, QSize
from PyQt5.QtGui import (QBrush, QIcon, QImage, QPainter, QPainterPath, QPen,
QPixmap, QTransform)
@@ -12,17 +15,19 @@ from shapes import SizeGripItem, directionsEnum
from .app import fileImporter
-
class ShapeDialog(QDialog):
-
+ """
+ The main dialog box for the custom symbol window.
+ """
def __init__(self, parent=None):
super(ShapeDialog, self).__init__(parent)
- self.resize(500, 300)
+ self.resize(500, 300) # resize to a fixed dim
self.setWindowTitle("Add New Shapes")
self.createLayout()
self.graphic = None
def createLayout(self):
+ #build layout for the dialog box
importButton = QPushButton("Import", self)
importButton.clicked.connect(self.importSVG)
@@ -80,6 +85,7 @@ class ShapeDialog(QDialog):
self.setLayout(layout)
def importSVG(self):
+ # Imports svg file through user input, adds it to the scene and stores it as a reference
self.name = QFileDialog.getOpenFileName(self, 'Open SVG File', '', 'Scalable Vector Graphics (*svg)')
if self.name:
self.graphic = QGraphicsSvgItem(self.name[0])
@@ -87,6 +93,9 @@ class ShapeDialog(QDialog):
self.painter.addItem(self.graphic)
def saveEvent(self):
+ # executes the build procedure
+
+ #check if all necessary values are there, each is seperate to show qalerts later on
if self.graphic is None:
return
@@ -102,10 +111,9 @@ class ShapeDialog(QDialog):
if category == "":
category = "misc"
+ # get rect for calculating grip positions
graphicRect = self.graphic.boundingRect()
-
- QIcon
-
+
#save file
name = QFileDialog.getSaveFileName(self, 'Save Icon', className, 'PNG (*.png)')
if name:
@@ -113,6 +121,7 @@ class ShapeDialog(QDialog):
else:
return
+ #calculate grip positions and build a list
gripList = []
x, y, w, h = graphicRect.getRect()
for i in self.grips:
@@ -125,10 +134,12 @@ class ShapeDialog(QDialog):
entry.append(i.width)
gripList.append(entry)
-
+ # format list in class definition flavor
grips = ",\n ".join([str(i) for i in gripList]) if gripList else ""
if grips:
grips = "self.grips = [" + grips + "]\n"
+
+ # build output dialog box
temp = QDialog(self)
tempLayout = QBoxLayout(QBoxLayout.TopToBottom)
output = OutputBox(temp, f"""
@@ -159,15 +170,19 @@ class {className}(NodeItem):
return [i for i in self.painter.items() if isinstance(i, gripAbstract)]
def addGrip(self):
+ #adds a grip dot to the scene
grip = gripDot()
self.painter.addItem(grip)
def addLineGrip(self):
+ #adds a line grip item
rect = gripRect()
self.painter.addItem(rect)
class gripAbstract(QGraphicsItem):
-
+ """
+ Abstract class for mouse click behaviour
+ """
def __init__(self):
super(gripAbstract, self).__init__()
self.location = "top"
@@ -178,6 +193,10 @@ class gripAbstract(QGraphicsItem):
directionsEnum.index(self.location), False)
class gripRect(gripAbstract):
+ """
+ simulates line grip item with resizeablity
+ (Haha grip items on grip items. Progress)
+ """
def __init__(self, x=0, y=0, w=80, h=10 ):
super(gripRect, self).__init__()
self.rotation = 0
@@ -185,7 +204,8 @@ class gripRect(gripAbstract):
self.width = w
self.height = h
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
-
+
+ #bounding rect and paint need to be implemented
def boundingRect(self):
return QRectF(-self.width / 2, -self.height / 2, self.width, self.height)
@@ -193,8 +213,9 @@ class gripRect(gripAbstract):
painter.setPen(QPen(Qt.black, 1, Qt.SolidLine))
painter.setBrush(QBrush(Qt.red))
painter.drawRect(self.boundingRect())
-
+
def addGripItems(self):
+ # adds the resizeable line grip items from the shape file :D
for i, (direction) in enumerate((Qt.Vertical,
Qt.Horizontal,
Qt.Vertical,
@@ -202,12 +223,14 @@ class gripRect(gripAbstract):
self.sizeGripItems.append(SizeGripItem(i, direction, parent=self))
def updateSizeGripItem(self, index_no_updates=None):
+ #update positions for existing grip items
index_no_updates = index_no_updates or []
for i, item in enumerate(self.sizeGripItems):
if i not in index_no_updates:
item.updatePosition()
def itemChange(self, change, value):
+ #do the needful when item is updated
if change == QGraphicsItem.ItemPositionHasChanged:
# update grips
self.updateSizeGripItem()
@@ -221,6 +244,7 @@ class gripRect(gripAbstract):
return super(gripRect, self).itemChange(change, value)
def resize(self, index, movement):
+ #resize method
self.prepareGeometryChange()
if index in [0, 1]:
self.width -= movement.x()
@@ -233,7 +257,10 @@ class gripRect(gripAbstract):
self.setTransform(transform, True)
self.updateSizeGripItem([index])
-class gripDot(gripAbstract):
+class gripDot(gripAbstract):
+ """
+ class for circular grips
+ """
def boundingRect(self):
return QRectF(0, 0, 10, 10)
@@ -243,9 +270,20 @@ class gripDot(gripAbstract):
painter.drawEllipse(self.boundingRect())
class OutputBox(QTextEdit):
-
+ """
+ Defines a read only text box for class output
+ """
def __init__(self, parent, text):
super(OutputBox, self).__init__(parent)
self.setReadOnly(True)
self.setFontWeight(10)
- self.setHtml(text) \ No newline at end of file
+ self.setHtml(text)
+
+if __name__ == '__main__': # 1. Instantiate ApplicationContext
+ #if app is launched directly
+ from .app import app
+ import sys
+ main = ShapeDialog()
+ main.show()
+ exit_code = app.app.exec_() # 2. Invoke app.app.exec_()
+ sys.exit(exit_code) \ No newline at end of file
diff --git a/src/main/python/utils/dialogs.py b/src/main/python/utils/dialogs.py
index f2c4eb9..043597c 100644
--- a/src/main/python/utils/dialogs.py
+++ b/src/main/python/utils/dialogs.py
@@ -110,6 +110,7 @@ def saveEvent(parent = None):
return True
def showUndoDialog(undoView, parent):
+ # helper function to show a dialog box containing the undo view
dialogBox = QDialog(parent)
dialogBox.resize(400, 400)
layout = QHBoxLayout(dialogBox)
diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py
index b2f5304..7ea5619 100644
--- a/src/main/python/utils/fileWindow.py
+++ b/src/main/python/utils/fileWindow.py
@@ -39,6 +39,7 @@ class FileWindow(QMdiSubWindow):
layout = QHBoxLayout(self.mainWidget)
self.createSideViewArea() #create the side view objects
+ # set size policies for window
left = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
left.setHorizontalStretch(1)
self.tabber.setSizePolicy(left)
@@ -47,8 +48,8 @@ class FileWindow(QMdiSubWindow):
right.setHorizontalStretch(1)
self.sideView.setSizePolicy(right)
+ #build widget layout
layout.addWidget(self.tabber)
- # layout.addWidget(self.splitter)
layout.addWidget(self.sideView)
self.mainWidget.setLayout(layout)
self.setWidget(self.mainWidget)
@@ -66,7 +67,6 @@ class FileWindow(QMdiSubWindow):
def createSideViewArea(self):
#creates the side view widgets and sets them to invisible
- # self.splitter = QSplitter(Qt.Vertical ,self)
self.sideView = CustomView(parent = self)
self.sideView.setInteractive(False)
self.sideViewCloseButton = QPushButton('×', self.sideView)
@@ -75,7 +75,6 @@ class FileWindow(QMdiSubWindow):
self.sideViewCloseButton.setFixedSize(20, 20)
self.moveSideViewCloseButton()
self.sideViewCloseButton.clicked.connect(lambda: setattr(self, 'sideViewTab', None))
- # self.splitter.setVisible(False)
self.sideView.setVisible(False)
self.sideView.setContextMenuPolicy(Qt.CustomContextMenu)
self.sideView.customContextMenuRequested.connect(self.sideViewContextMenu)
@@ -127,13 +126,11 @@ class FileWindow(QMdiSubWindow):
def sideViewToggle(self):
#Function checks if current side view tab is set, and toggles view as required
if self.sideViewTab:
- # self.splitter.setVisible(True)
self.sideView.setVisible(True)
self.sideView.setScene(self.tabber.currentWidget().painter)
self.resizeHandler()
return True
- else:
- # self.splitter.setVisible(False)
+ else:
self.sideView.setVisible(False)
self.resizeHandler()
return False
@@ -163,6 +160,7 @@ class FileWindow(QMdiSubWindow):
menu.exec_(self.sideView.mapToGlobal(point))
def sideViewSwitchCMenu(self, index):
+ # helper function to swtich side view tab
self.sideViewTab = self.tabber.widget(index)
def sideViewSwitchTab(self):
@@ -234,8 +232,7 @@ class FileWindow(QMdiSubWindow):
else:
event.ignore()
- #following 2 methods are defined for correct pickling of the scene. may be changed to json or xml later so as
- # to not have a binary file.
+ #following 2 methods are defined for correct serialization of the scene.
def __getstate__(self) -> dict:
return {
"_classname_": self.__class__.__name__,
diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py
index 05ffc46..bb113ce 100644
--- a/src/main/python/utils/graphics.py
+++ b/src/main/python/utils/graphics.py
@@ -20,12 +20,6 @@ class CustomView(QGraphicsView):
self._zoom = 1
self.setDragMode(True) #sets pannable using mouse
self.setAcceptDrops(True) #sets ability to accept drops
- if scene:
- #create necessary undo redo actions to accept keyboard shortcuts
- # self.addAction(scene.undoAction)
- # self.addAction(scene.redoAction)
- # self.addAction(scene.deleteAction)
- pass
#following four functions are required to be overridden for drag-drop functionality
def dragEnterEvent(self, QDragEnterEvent):
@@ -48,8 +42,6 @@ class CustomView(QGraphicsView):
#QDropEvent.mimeData().text() defines intended drop item, the pos values define position
obj = QDropEvent.mimeData().text().split('/')
graphic = getattr(shapes, obj[0])(*map(lambda x: int(x) if x.isdigit() else x, obj[1:]))
- # graphic.setPen(QPen(Qt.black, 2))
- # graphic.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable)
graphic.setPos(QDropEvent.pos().x(), QDropEvent.pos().y())
self.scene().addItemPlus(graphic)
QDropEvent.acceptProposedAction()
diff --git a/src/main/python/utils/layout.py b/src/main/python/utils/layout.py
index b977a68..e1354b0 100644
--- a/src/main/python/utils/layout.py
+++ b/src/main/python/utils/layout.py
@@ -2,6 +2,10 @@ from PyQt5.QtCore import Qt, QRect, QPoint, QSize
from PyQt5.QtWidgets import QLayout, QSizePolicy
class flowLayout(QLayout):
+ """
+ Custom layout that flows horizontally first, then vertically.
+ From Qt examples.
+ """
def __init__(self, parent=None, margin=0, spacing=12):
super(flowLayout, self).__init__(parent)
@@ -12,46 +16,57 @@ class flowLayout(QLayout):
self.itemList = []
def __del__(self):
+ # Delete layout call
item = self.takeAt(0)
while item:
item = self.takeAt(0)
def addItem(self, item):
+ # add item to layout
self.itemList.append(item)
def count(self):
+ # return a list of items
return len(self.itemList)
def itemAt(self, index):
+ # return item at index
if index >= 0 and index < len(self.itemList):
return self.itemList[index]
return None
def takeAt(self, index):
+ # pop item at index
if index >= 0 and index < len(self.itemList):
return self.itemList.pop(index)
return None
def expandingDirections(self):
+ # define orientation
return Qt.Orientations(Qt.Orientation(0))
def hasHeightForWidth(self):
+ # height for width flag, height value for a particular width
return True
def heightForWidth(self, width):
+ # returns the height for a given width
height = self.doLayout(QRect(0, 0, width, 0), True)
return height
def setGeometry(self, rect):
+ # change layout geometry
super(flowLayout, self).setGeometry(rect)
self.doLayout(rect, False)
def sizeHint(self):
+ # returns the expected size
return self.minimumSize()
def minimumSize(self):
+ # calucalate minimum possible size below which, resize is impossible
size = QSize()
for item in self.itemList:
@@ -63,6 +78,7 @@ class flowLayout(QLayout):
return size
def doLayout(self, rect, testOnly):
+ # build layout, testOnly defines if the geometry needs to be changed or not
x = rect.x()
y = rect.y()
lineHeight = 0
diff --git a/src/main/python/utils/streamTable.py b/src/main/python/utils/streamTable.py
index c8e682c..8b3b220 100644
--- a/src/main/python/utils/streamTable.py
+++ b/src/main/python/utils/streamTable.py
@@ -5,13 +5,17 @@ from PyQt5.QtWidgets import QTableView, QMenu, QGraphicsRectItem, QInputDialog,
from collections import defaultdict
class streamTableModel(QAbstractTableModel):
+ """
+ Defines the table model for the table view
+ """
updateEvent = pyqtSignal()
def __init__(self, parent, list, header, *args):
super(streamTableModel, self).__init__(parent, *args)
self.list = list
self.header = header
-
+
+ # column count, row count, data and setdata are important methods to be overloaded
def columnCount(self, parent=None):
return len(self.list)
@@ -19,31 +23,41 @@ class streamTableModel(QAbstractTableModel):
return len(self.header)
def data(self, index, role):
+ # retunrs data at index
if role == Qt.TextAlignmentRole:
return Qt.AlignHCenter
+
if role == Qt.BackgroundColorRole:
return Qt.white
+
if not index.isValid():
return None
+
elif role != Qt.DisplayRole:
return None
+
if index.row() == 0:
- return self.list[index.column()].toPlainText()
+ return self.list[index.column()].toPlainText() # return label name
else:
- return self.list[index.column()].values[self.header[index.row()]]
+ return self.list[index.column()].values[self.header[index.row()]] # retunr label values
def setData(self, index, value, role):
+ # defines how to manipulate data at a given index with value returns sucess value
if not index.isValid():
return False
+
elif role != Qt.EditRole:
return False
+
if index.row() == 0:
- self.list[index.column()].setPlainText(value)
+ self.list[index.column()].setPlainText(value) # change label text
else:
- self.list[index.column()].values[self.header[index.row()]] = value
+ self.list[index.column()].values[self.header[index.row()]] = value #change label values
+
return True
def insertColumn(self, int=None, item=None):
+ # inserting a label item
int = int if int else self.rowCount()+1
self.beginInsertColumns(QModelIndex(), int, int)
self.list.insert(int, item)
@@ -52,54 +66,65 @@ class streamTableModel(QAbstractTableModel):
self.updateEvent.emit()
def insertRow(self, int=None, name="newVal"):
+ # inserting a header property
self.beginInsertRows(QModelIndex(), int, int)
self.header.insert(int, name)
self.endInsertRows()
self.updateEvent.emit()
def deleteRow(self, row):
+ # removing a property
self.beginRemoveRows(QModelIndex(), row, row)
- valName = self.header.pop(row)
+ valName = self.header.pop(row) # remove from header
self.endRemoveRows()
+
for i in self.list:
- i.values.pop(valName)
- self.updateEvent.emit()
+ i.values.pop(valName) #clear dictionary
+
+ self.updateEvent.emit() # update request
def headerData(self, col, orientation, role):
+ # definds how to fetch header data
if orientation == Qt.Vertical and role == Qt.DisplayRole:
return self.header[col]
return None
def flags(self, index):
+ # defines item editable flag
return (super(streamTableModel, self).flags(index) | Qt.ItemIsEditable)
class streamTable(QTableView):
-
+ """
+ subclasses stream table to display data properly
+ """
def __init__(self, itemLabels=[], canvas=None, parent=None):
super(streamTable, self).__init__(parent=parent)
self.canvas = canvas
+
for i in itemLabels:
- i.nameChanged.connect(self.repaint)
- header = ["name", "val1", "val2", "val3", "val4", "val5"]
+ i.nameChanged.connect(self.repaint) # connect repaint requests on name change
+
+ header = ["name", "val1", "val2", "val3", "val4", "val5"] # prepare header names
self.model = streamTableModel(self, itemLabels, header)
- self.setShowGrid(False)
+ self.setShowGrid(False) # disable table grid
- self.horizontalHeader().hide()
- header = verticalHeader(Qt.Vertical, self)
+ self.horizontalHeader().hide() # remove horizontal header
+
+ header = verticalHeader(Qt.Vertical, self) #create custom vertical header
self.setVerticalHeader(header)
header.labelChangeRequested.connect(self.labelChange)
- self.setModel(self.model)
- self.borderThickness = defaultdict(lambda: False)
+ self.setModel(self.model) #declare model
+ self.borderThickness = defaultdict(lambda: False) #thickness bool dict
self.model.updateEvent.connect(self.resizeHandler)
self.setItemDelegateForRow(0, drawBorderDelegate(self))
- self.borderThickness[0] = True
+ self.borderThickness[0] = True # set border true for name row
def mousePressEvent(self, event):
+ # handle context menu request
if event.button() == Qt.RightButton:
point = event.pos()
- # col = self.getCol(point.x())
index = self.indexAt(point)
menu = QMenu("Context Menu", self)
menu.addAction("Toggle bottom border thickness", lambda x=index.row(): self.changeRowBorder(x))
@@ -110,6 +135,7 @@ class streamTable(QTableView):
return super(streamTable, self).mousePressEvent(event)
def changeRowBorder(self, row):
+ # toggle column border thicnkess
if self.borderThickness[row]:
self.borderThickness.pop(row)
self.setItemDelegateForRow(row, QStyledItemDelegate(self))
@@ -119,6 +145,7 @@ class streamTable(QTableView):
self.verticalHeader().repaint()
def labelChange(self, index):
+ # label name change
newName, bool = QInputDialog.getText(self, "Change Property Name", "Enter new name",
text = self.model.header[index])
if bool:
@@ -128,6 +155,7 @@ class streamTable(QTableView):
self.repaint()
def insertRowBottom(self, row):
+ # dialog box for new property
name, bool = QInputDialog.getText(self, "New Property", "Enter name",
text = "newVal")
if bool:
@@ -162,10 +190,9 @@ class streamTable(QTableView):
self.repaint()
class drawBorderDelegate(QStyledItemDelegate):
-
- # def __init__(self, parent):
- # super(drawBorderDelegate, self).__init__(parent)
-
+ """
+ class for drawing border line
+ """
def paint(self, painter, option, index):
rect = option.rect
painter.drawLine(rect.bottomLeft(), rect.bottomRight())
@@ -173,7 +200,9 @@ class drawBorderDelegate(QStyledItemDelegate):
super(drawBorderDelegate, self).paint(painter, option, index)
class moveRect(QGraphicsRectItem):
-
+ """
+ use to move the table on the scene
+ """
def __init__(self, sideLength = 15, *args):
super(moveRect, self).__init__(-sideLength, -sideLength, sideLength, sideLength)
self.setBrush(Qt.transparent)
@@ -190,6 +219,9 @@ class moveRect(QGraphicsRectItem):
return super(moveRect, self).hoverLeaveEvent(event)
class verticalHeader(QHeaderView):
+ """
+ Custom Vertical header for the table, with line border against corresponding rows
+ """
labelChangeRequested = pyqtSignal(int)
def mouseDoubleClickEvent(self, event):
diff --git a/src/main/python/utils/tabs.py b/src/main/python/utils/tabs.py
index cedb298..70f9def 100644
--- a/src/main/python/utils/tabs.py
+++ b/src/main/python/utils/tabs.py
@@ -3,7 +3,7 @@ from PyQt5.QtCore import pyqtSignal, QSize, Qt
class TabBarPlus(QTabBar):
"""
- Just implemented to overload resize and layout change to emit a signal
+ Just implemented to overload resize and layout change to emit a signal and change tab names.
"""
layoutChanged = pyqtSignal()
nameChanged = pyqtSignal(int, str)
@@ -16,6 +16,7 @@ class TabBarPlus(QTabBar):
self.layoutChanged.emit()
def mouseDoubleClickEvent(self, event):
+ # tab name change request
if event.button() != Qt.LeftButton:
return super().mouseDoubleClickEvent()
index = self.currentIndex()
diff --git a/src/main/python/utils/toolbar.py b/src/main/python/utils/toolbar.py
index 3f6338b..f2bbd5a 100644
--- a/src/main/python/utils/toolbar.py
+++ b/src/main/python/utils/toolbar.py
@@ -9,8 +9,6 @@ from .data import toolbarItems
from .app import fileImporter, app
from .layout import flowLayout
-# resourceManager = ApplicationContext() #Used to load images, mainly toolbar icons
-
class toolbar(QDockWidget):
"""
Defines the right side toolbar, using QDockWidget.
diff --git a/src/main/python/utils/undo.py b/src/main/python/utils/undo.py
index 92a8de8..6a46b27 100644
--- a/src/main/python/utils/undo.py
+++ b/src/main/python/utils/undo.py
@@ -91,6 +91,7 @@ class moveCommand(QUndoCommand):
class resizeCommand(QUndoCommand):
"""
+ Defines the resize event for the custom scene.
"""
def __init__(self, new, canvas, widget, parent = None):
super(resizeCommand, self).__init__(parent)