From bf7fef5bca9044a8faec498eaa54889f0a9fe57b Mon Sep 17 00:00:00 2001 From: Blaine Date: Mon, 20 Apr 2020 17:52:05 +0530 Subject: FBS INIT --- src/build/settings/base.json | 6 ++++++ src/build/settings/linux.json | 6 ++++++ src/build/settings/mac.json | 3 +++ src/main/icons/Icon.ico | Bin 0 -> 168229 bytes src/main/icons/README.md | 11 +++++++++++ src/main/icons/base/16.png | Bin 0 -> 544 bytes src/main/icons/base/24.png | Bin 0 -> 783 bytes src/main/icons/base/32.png | Bin 0 -> 912 bytes src/main/icons/base/48.png | Bin 0 -> 1497 bytes src/main/icons/base/64.png | Bin 0 -> 1657 bytes src/main/icons/linux/1024.png | Bin 0 -> 26841 bytes src/main/icons/linux/128.png | Bin 0 -> 3177 bytes src/main/icons/linux/256.png | Bin 0 -> 5641 bytes src/main/icons/linux/512.png | Bin 0 -> 11653 bytes src/main/icons/mac/1024.png | Bin 0 -> 47311 bytes src/main/icons/mac/128.png | Bin 0 -> 4978 bytes src/main/icons/mac/256.png | Bin 0 -> 10278 bytes src/main/icons/mac/512.png | Bin 0 -> 21699 bytes src/main/python/main.py | 12 ++++++++++++ 19 files changed, 38 insertions(+) create mode 100644 src/build/settings/base.json create mode 100644 src/build/settings/linux.json create mode 100644 src/build/settings/mac.json create mode 100644 src/main/icons/Icon.ico create mode 100644 src/main/icons/README.md create mode 100644 src/main/icons/base/16.png create mode 100644 src/main/icons/base/24.png create mode 100644 src/main/icons/base/32.png create mode 100644 src/main/icons/base/48.png create mode 100644 src/main/icons/base/64.png create mode 100644 src/main/icons/linux/1024.png create mode 100644 src/main/icons/linux/128.png create mode 100644 src/main/icons/linux/256.png create mode 100644 src/main/icons/linux/512.png create mode 100644 src/main/icons/mac/1024.png create mode 100644 src/main/icons/mac/128.png create mode 100644 src/main/icons/mac/256.png create mode 100644 src/main/icons/mac/512.png create mode 100644 src/main/python/main.py (limited to 'src') diff --git a/src/build/settings/base.json b/src/build/settings/base.json new file mode 100644 index 0000000..e6321bb --- /dev/null +++ b/src/build/settings/base.json @@ -0,0 +1,6 @@ +{ + "app_name": "PFD-Tool", + "author": "FOSSEE", + "main_module": "src/main/python/main.py", + "version": "0.0.0" +} \ No newline at end of file diff --git a/src/build/settings/linux.json b/src/build/settings/linux.json new file mode 100644 index 0000000..7a64c95 --- /dev/null +++ b/src/build/settings/linux.json @@ -0,0 +1,6 @@ +{ + "categories": "Utility;", + "description": "", + "author_email": "", + "url": "" +} \ No newline at end of file diff --git a/src/build/settings/mac.json b/src/build/settings/mac.json new file mode 100644 index 0000000..f7bd610 --- /dev/null +++ b/src/build/settings/mac.json @@ -0,0 +1,3 @@ +{ + "mac_bundle_identifier": "" +} \ No newline at end of file diff --git a/src/main/icons/Icon.ico b/src/main/icons/Icon.ico new file mode 100644 index 0000000..3312d86 Binary files /dev/null and b/src/main/icons/Icon.ico differ diff --git a/src/main/icons/README.md b/src/main/icons/README.md new file mode 100644 index 0000000..c6c4194 --- /dev/null +++ b/src/main/icons/README.md @@ -0,0 +1,11 @@ +![Sample app icon](linux/128.png) + +This directory contains the icons that are displayed for your app. Feel free to +change them. + +The difference between the icons on Mac and the other platforms is that on Mac, +they contain a ~5% transparent margin. This is because otherwise they look too +big (eg. in the Dock or in the app switcher). + +You can create Icon.ico from the .png files with +[an online tool](http://icoconvert.com/Multi_Image_to_one_icon/). \ No newline at end of file diff --git a/src/main/icons/base/16.png b/src/main/icons/base/16.png new file mode 100644 index 0000000..f7d02dc Binary files /dev/null and b/src/main/icons/base/16.png differ diff --git a/src/main/icons/base/24.png b/src/main/icons/base/24.png new file mode 100644 index 0000000..faa6710 Binary files /dev/null and b/src/main/icons/base/24.png differ diff --git a/src/main/icons/base/32.png b/src/main/icons/base/32.png new file mode 100644 index 0000000..36b25e8 Binary files /dev/null and b/src/main/icons/base/32.png differ diff --git a/src/main/icons/base/48.png b/src/main/icons/base/48.png new file mode 100644 index 0000000..4a5dcbd Binary files /dev/null and b/src/main/icons/base/48.png differ diff --git a/src/main/icons/base/64.png b/src/main/icons/base/64.png new file mode 100644 index 0000000..4b0a423 Binary files /dev/null and b/src/main/icons/base/64.png differ diff --git a/src/main/icons/linux/1024.png b/src/main/icons/linux/1024.png new file mode 100644 index 0000000..2248377 Binary files /dev/null and b/src/main/icons/linux/1024.png differ diff --git a/src/main/icons/linux/128.png b/src/main/icons/linux/128.png new file mode 100644 index 0000000..05b2b35 Binary files /dev/null and b/src/main/icons/linux/128.png differ diff --git a/src/main/icons/linux/256.png b/src/main/icons/linux/256.png new file mode 100644 index 0000000..578fdc7 Binary files /dev/null and b/src/main/icons/linux/256.png differ diff --git a/src/main/icons/linux/512.png b/src/main/icons/linux/512.png new file mode 100644 index 0000000..0fbac4f Binary files /dev/null and b/src/main/icons/linux/512.png differ diff --git a/src/main/icons/mac/1024.png b/src/main/icons/mac/1024.png new file mode 100644 index 0000000..c1c8691 Binary files /dev/null and b/src/main/icons/mac/1024.png differ diff --git a/src/main/icons/mac/128.png b/src/main/icons/mac/128.png new file mode 100644 index 0000000..de9bee6 Binary files /dev/null and b/src/main/icons/mac/128.png differ diff --git a/src/main/icons/mac/256.png b/src/main/icons/mac/256.png new file mode 100644 index 0000000..c3a68b9 Binary files /dev/null and b/src/main/icons/mac/256.png differ diff --git a/src/main/icons/mac/512.png b/src/main/icons/mac/512.png new file mode 100644 index 0000000..b2fc07e Binary files /dev/null and b/src/main/icons/mac/512.png differ diff --git a/src/main/python/main.py b/src/main/python/main.py new file mode 100644 index 0000000..18c8d38 --- /dev/null +++ b/src/main/python/main.py @@ -0,0 +1,12 @@ +from fbs_runtime.application_context.PyQt5 import ApplicationContext +from PyQt5.QtWidgets import QMainWindow + +import sys + +if __name__ == '__main__': + appctxt = ApplicationContext() # 1. Instantiate ApplicationContext + window = QMainWindow() + window.resize(250, 150) + window.show() + exit_code = appctxt.app.exec_() # 2. Invoke appctxt.app.exec_() + sys.exit(exit_code) \ No newline at end of file -- cgit From 59fed433c9fd8af5738f5ae7199e517a34da9e55 Mon Sep 17 00:00:00 2001 From: Blaine Date: Mon, 20 Apr 2020 18:52:25 +0530 Subject: resizeable window --- src/main/python/main.py | 81 +++++++++++++++++++++++++++++++++++---- src/main/python/utils/__init__.py | 0 src/main/python/utils/sizes.py | 32 ++++++++++++++++ 3 files changed, 106 insertions(+), 7 deletions(-) create mode 100644 src/main/python/utils/__init__.py create mode 100644 src/main/python/utils/sizes.py (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 18c8d38..88fc48b 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -1,12 +1,79 @@ from fbs_runtime.application_context.PyQt5 import ApplicationContext -from PyQt5.QtWidgets import QMainWindow - +from PyQt5.QtCore import Qt +from PyQt5.QtGui import (QBrush, QColor, QImage, QPainter, + QPalette) +from PyQt5.QtWidgets import (QApplication, QComboBox, QDialog, QGraphicsScene, + QGraphicsView, QGridLayout, QHBoxLayout, QLabel, + QMessageBox, QPushButton, QStyleFactory) +from utils.sizes import paperSizes import sys +class appWindow(QDialog): + def __init__(self, parent=None): + super(appWindow, self).__init__(parent) + + self._ppi = 72 + self._canvasSize = "A0" + self.resize(1280, 720) + + + self.painter = QGraphicsScene(0, 0, *paperSizes[self.canvasSize][self.ppi]) + self.painter.setBackgroundBrush(QBrush(Qt.white)) + + self.createToolbar() + self.canvas = QGraphicsView(self.painter) + mainLayout = QGridLayout() + mainLayout.addLayout(self.topLayout, 0, 0, 1, -1) + mainLayout.addWidget(self.canvas, 1, 0, -1, -1) + self.setLayout(mainLayout) + + def createToolbar(self): + self.topLayout = QHBoxLayout() + sizeComboBox = QComboBox() + sizeComboBox.addItems([f'A{i}' for i in range(5)]) + sizeComboBox.activated[str].connect(self.setCanvasSize) + sizeLabel = QLabel("Canvas Size") + sizeLabel.setBuddy(sizeComboBox) + self.topLayout.addWidget(sizeLabel) + self.topLayout.addWidget(sizeComboBox) + + ppiComboBox = QComboBox() + ppiComboBox.addItems(["72", "96", "150", "300"]) + ppiComboBox.activated[str].connect(self.setCanvasPPI) + ppiLabel = QLabel("Canvas ppi") + ppiLabel.setBuddy(ppiComboBox) + self.topLayout.addWidget(ppiLabel) + self.topLayout.addWidget(ppiComboBox) + + def setCanvasSize(self, size): + self.canvasSize = size + + def setCanvasPPI(self, ppi): + self.ppi = ppi + + @property + def canvasSize(self): + return self._canvasSize + @property + def ppi(self): + return self._ppi + + @canvasSize.setter + def canvasSize(self, size): + self._canvasSize = size + if self.painter: + self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) + print(*paperSizes[self.canvasSize][self.ppi]) + @ppi.setter + def ppi(self, ppi): + self._ppi = int(ppi) + if self.painter: + self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) + print(*paperSizes[self.canvasSize][self.ppi]) + if __name__ == '__main__': - appctxt = ApplicationContext() # 1. Instantiate ApplicationContext - window = QMainWindow() - window.resize(250, 150) - window.show() - exit_code = appctxt.app.exec_() # 2. Invoke appctxt.app.exec_() + app = ApplicationContext() # 1. Instantiate ApplicationContext + test = appWindow() + test.show() + exit_code = app.app.exec_() # 2. Invoke appctxt.app.exec_() sys.exit(exit_code) \ No newline at end of file diff --git a/src/main/python/utils/__init__.py b/src/main/python/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/main/python/utils/sizes.py b/src/main/python/utils/sizes.py new file mode 100644 index 0000000..fc444cf --- /dev/null +++ b/src/main/python/utils/sizes.py @@ -0,0 +1,32 @@ +paperSizes = { + "A0": { + 72: {2384, 3370}, + 96: {3179, 4494}, + 150: {4967, 7022}, + 300: {9933, 14043} + }, + "A1": { + 72: {1684, 2384}, + 96: {2245, 3179}, + 150: {3508, 4967}, + 300: {7016, 9933} + }, + "A2": { + 72: {1191, 1684}, + 96: {1587, 2245}, + 150: {2480, 3508}, + 300: {4960, 7016} + }, + "A3": { + 72: {842, 1191}, + 96: {1123, 1587}, + 150: {1754, 2480}, + 300: {3508, 4960} + }, + "A4": { + 72: {595, 842}, + 96: {794, 1123}, + 150: {1240, 1754}, + 300: {2480, 3508} + } +} \ No newline at end of file -- cgit From 16332668592bb1fcaa1b4f1bbd48c65bb55bc139 Mon Sep 17 00:00:00 2001 From: Blaine Date: Tue, 21 Apr 2020 16:55:43 +0530 Subject: Moved to QMainWindow. canvas is now seperate --- src/main/python/main.py | 87 +++++++++++++++++++++-------------------- src/main/python/utils/canvas.py | 46 ++++++++++++++++++++++ 2 files changed, 90 insertions(+), 43 deletions(-) create mode 100644 src/main/python/utils/canvas.py (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 88fc48b..b42329e 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -1,76 +1,77 @@ from fbs_runtime.application_context.PyQt5 import ApplicationContext -from PyQt5.QtCore import Qt +from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot, QObject from PyQt5.QtGui import (QBrush, QColor, QImage, QPainter, QPalette) -from PyQt5.QtWidgets import (QApplication, QComboBox, QDialog, QGraphicsScene, +from PyQt5.QtWidgets import (QWidget, QComboBox, QMainWindow, QGraphicsScene, QGraphicsView, QGridLayout, QHBoxLayout, QLabel, - QMessageBox, QPushButton, QStyleFactory) -from utils.sizes import paperSizes + QPushButton, QMenuBar, QMenu, QFormLayout, QTabWidget) + +from utils.canvas import canvas import sys -class appWindow(QDialog): + +class appWindow(QMainWindow): def __init__(self, parent=None): - super(appWindow, self).__init__(parent) - - self._ppi = 72 - self._canvasSize = "A0" + super(appWindow, self).__init__(parent) self.resize(1280, 720) - - self.painter = QGraphicsScene(0, 0, *paperSizes[self.canvasSize][self.ppi]) - self.painter.setBackgroundBrush(QBrush(Qt.white)) + titleMenu = self.menuBar() + self.mainWidget = QWidget(self) + self.menuFile = titleMenu.addMenu('File') #File Menu + self.menuFile.addAction("new", self.newDiagram) + self.menuGenerate = titleMenu.addMenu('Generate') #Generate menu + self.menuGenerate.addAction("Image", self.saveImage) + self.menuGenerate.addAction("Report", self.generateReport) + + + mainLayout = QGridLayout(self.mainWidget) + self.tabber = QTabWidget(self.mainWidget) + self.tabber.setTabsClosable(True) + # QObject.connect(self.tabber, pyqtSignal(QTabWidget.tabCloseRequested(int)), self, pyqtSlot(QTabWidget.closetab(int))) + # add close action to tabs self.createToolbar() - self.canvas = QGraphicsView(self.painter) - mainLayout = QGridLayout() - mainLayout.addLayout(self.topLayout, 0, 0, 1, -1) - mainLayout.addWidget(self.canvas, 1, 0, -1, -1) - self.setLayout(mainLayout) + mainLayout.addLayout(self.toolbar, 0, 0, -1, 2) + mainLayout.addWidget(self.tabber, 0, 2, -1, 10) + + self.mainWidget.setLayout(mainLayout) + self.setCentralWidget(self.mainWidget) def createToolbar(self): - self.topLayout = QHBoxLayout() + self.toolbar = QFormLayout(self.mainWidget) sizeComboBox = QComboBox() sizeComboBox.addItems([f'A{i}' for i in range(5)]) + # sizeComboBox.activated[str].connect(lambda: self.tabber.currentWidget().setCanvasSize) sizeComboBox.activated[str].connect(self.setCanvasSize) sizeLabel = QLabel("Canvas Size") sizeLabel.setBuddy(sizeComboBox) - self.topLayout.addWidget(sizeLabel) - self.topLayout.addWidget(sizeComboBox) + self.toolbar.setWidget(0, QFormLayout.LabelRole, sizeLabel) + self.toolbar.setWidget(0, QFormLayout.FieldRole, sizeComboBox) ppiComboBox = QComboBox() ppiComboBox.addItems(["72", "96", "150", "300"]) + # ppiComboBox.activated[str].connect(lambda: self.tabber.currentWidget().setCanvasPPI) ppiComboBox.activated[str].connect(self.setCanvasPPI) ppiLabel = QLabel("Canvas ppi") ppiLabel.setBuddy(ppiComboBox) - self.topLayout.addWidget(ppiLabel) - self.topLayout.addWidget(ppiComboBox) + self.toolbar.setWidget(1, QFormLayout.LabelRole, ppiLabel) + self.toolbar.setWidget(1, QFormLayout.FieldRole, ppiComboBox) def setCanvasSize(self, size): - self.canvasSize = size + self.tabber.currentWidget().canvasSize = size def setCanvasPPI(self, ppi): - self.ppi = ppi + self.tabber.currentWidget().ppi = ppi + + def newDiagram(self): + diagram = canvas() + self.tabber.addTab(diagram, "New") - @property - def canvasSize(self): - return self._canvasSize - @property - def ppi(self): - return self._ppi + def saveImage(self): + pass - @canvasSize.setter - def canvasSize(self, size): - self._canvasSize = size - if self.painter: - self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) - print(*paperSizes[self.canvasSize][self.ppi]) + def generateReport(self): + pass - @ppi.setter - def ppi(self, ppi): - self._ppi = int(ppi) - if self.painter: - self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) - print(*paperSizes[self.canvasSize][self.ppi]) - if __name__ == '__main__': app = ApplicationContext() # 1. Instantiate ApplicationContext test = appWindow() diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py new file mode 100644 index 0000000..ad72544 --- /dev/null +++ b/src/main/python/utils/canvas.py @@ -0,0 +1,46 @@ +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QBrush +from PyQt5.QtWidgets import QWidget, QGraphicsScene, QGraphicsView, QHBoxLayout +from .sizes import paperSizes +class canvas(QWidget): + def __init__(self, parent=None): + super(canvas, self).__init__(parent) + + self._ppi = 72 + self._canvasSize = "A0" + self.resize(1280, 720) + + + self.painter = QGraphicsScene(0, 0, *paperSizes[self.canvasSize][self.ppi]) + self.painter.setBackgroundBrush(QBrush(Qt.white)) + self.view = QGraphicsView(self.painter) + self.layout = QHBoxLayout(self) + self.layout.addWidget(self.view) + self.setLayout(self.layout) + + def setCanvasSize(self, size): + self.canvasSize = size + + def setCanvasPPI(self, ppi): + self.ppi = ppi + + @property + def canvasSize(self): + return self._canvasSize + @property + def ppi(self): + return self._ppi + + @canvasSize.setter + def canvasSize(self, size): + self._canvasSize = size + if self.painter: + self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) + # print(*paperSizes[self.canvasSize][self.ppi]) + + @ppi.setter + def ppi(self, ppi): + self._ppi = int(ppi) + if self.painter: + self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) + # print(*paperSizes[self.canvasSize][self.ppi]) \ No newline at end of file -- cgit From f661c76ccfa3f72f1f20055bb670f41e59080179 Mon Sep 17 00:00:00 2001 From: Blaine Date: Tue, 21 Apr 2020 17:10:08 +0530 Subject: defaults for ppi/size, fixed? weird bev on tab add --- src/main/python/main.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index b42329e..fa615ff 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -13,6 +13,8 @@ class appWindow(QMainWindow): def __init__(self, parent=None): super(appWindow, self).__init__(parent) self.resize(1280, 720) + self._defaultPPI = 72 + self._defaultCanvasSize = "A0" titleMenu = self.menuBar() self.mainWidget = QWidget(self) @@ -30,7 +32,7 @@ class appWindow(QMainWindow): # QObject.connect(self.tabber, pyqtSignal(QTabWidget.tabCloseRequested(int)), self, pyqtSlot(QTabWidget.closetab(int))) # add close action to tabs self.createToolbar() - mainLayout.addLayout(self.toolbar, 0, 0, -1, 2) + mainLayout.addLayout(self.toolbar, 0, 0, -1, 1) mainLayout.addWidget(self.tabber, 0, 2, -1, 10) self.mainWidget.setLayout(mainLayout) @@ -57,13 +59,19 @@ class appWindow(QMainWindow): self.toolbar.setWidget(1, QFormLayout.FieldRole, ppiComboBox) def setCanvasSize(self, size): - self.tabber.currentWidget().canvasSize = size + self._defaultCanvasSize = size + activeCanvas = self.tabber.currentWidget() + if activeCanvas: + activeCanvas.canvasSize = size - def setCanvasPPI(self, ppi): - self.tabber.currentWidget().ppi = ppi + def setCanvasPPI(self, ppi): + self._defaultPPI = ppi + activeCanvas = self.tabber.currentWidget() + if activeCanvas: + activeCanvas.ppi = ppi def newDiagram(self): - diagram = canvas() + diagram = canvas(size = self._defaultCanvasSize, ppi = self._defaultPPI) self.tabber.addTab(diagram, "New") def saveImage(self): -- cgit From 20a3d0c0d2a2918ed7e424961edd08c5636f8162 Mon Sep 17 00:00:00 2001 From: Blaine Date: Tue, 21 Apr 2020 17:10:29 +0530 Subject: defaults for canvassize and ppi --- src/main/python/utils/canvas.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index ad72544..258d901 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -3,11 +3,11 @@ from PyQt5.QtGui import QBrush from PyQt5.QtWidgets import QWidget, QGraphicsScene, QGraphicsView, QHBoxLayout from .sizes import paperSizes class canvas(QWidget): - def __init__(self, parent=None): + def __init__(self, parent=None, size= "A0", ppi= 72): super(canvas, self).__init__(parent) - self._ppi = 72 - self._canvasSize = "A0" + self._ppi = ppi + self._canvasSize = size self.resize(1280, 720) -- cgit From 6416c34f957b2f0d2c5de318dc7023f9f67e9042 Mon Sep 17 00:00:00 2001 From: Blaine Date: Tue, 21 Apr 2020 17:27:43 +0530 Subject: fixed tab close --- src/main/python/main.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index fa615ff..c19e7c7 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -29,7 +29,7 @@ class appWindow(QMainWindow): mainLayout = QGridLayout(self.mainWidget) self.tabber = QTabWidget(self.mainWidget) self.tabber.setTabsClosable(True) - # QObject.connect(self.tabber, pyqtSignal(QTabWidget.tabCloseRequested(int)), self, pyqtSlot(QTabWidget.closetab(int))) + self.tabber.tabCloseRequested.connect(self.closeTab) # add close action to tabs self.createToolbar() mainLayout.addLayout(self.toolbar, 0, 0, -1, 1) @@ -37,7 +37,12 @@ class appWindow(QMainWindow): self.mainWidget.setLayout(mainLayout) self.setCentralWidget(self.mainWidget) - + + def closeTab(self, currentIndex): + #todo add save alert + self.tabber.widget(currentIndex).deleteLater() + self.tabber.removeTab(currentIndex) + def createToolbar(self): self.toolbar = QFormLayout(self.mainWidget) sizeComboBox = QComboBox() -- cgit From 89eeec65b7307df11c59d9dca8089f0ae62b3a47 Mon Sep 17 00:00:00 2001 From: Blaine Date: Wed, 22 Apr 2020 12:38:53 +0530 Subject: Switching tabs, updates combo box values --- src/main/python/main.py | 62 ++++++++++++++++++++++++++++------------- src/main/python/utils/canvas.py | 15 ++++------ src/main/python/utils/sizes.py | 46 ++++++++++++++++-------------- 3 files changed, 73 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index c19e7c7..ebc80a2 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -7,6 +7,7 @@ from PyQt5.QtWidgets import (QWidget, QComboBox, QMainWindow, QGraphicsScene, QPushButton, QMenuBar, QMenu, QFormLayout, QTabWidget) from utils.canvas import canvas +from utils.sizes import sheetDimensionList, ppiList import sys class appWindow(QMainWindow): @@ -18,50 +19,62 @@ class appWindow(QMainWindow): titleMenu = self.menuBar() self.mainWidget = QWidget(self) + self.mainWidget.setObjectName("Main Widget") self.menuFile = titleMenu.addMenu('File') #File Menu - self.menuFile.addAction("new", self.newDiagram) + self.menuFile.addAction("New", self.newDiagram) + self.menuFile.addAction("Open", self.openDiagram) + self.menuFile.addAction("Save", self.saveDiagram) self.menuGenerate = titleMenu.addMenu('Generate') #Generate menu self.menuGenerate.addAction("Image", self.saveImage) self.menuGenerate.addAction("Report", self.generateReport) - mainLayout = QGridLayout(self.mainWidget) + mainLayout.setObjectName("Main Layout") + self.tabber = QTabWidget(self.mainWidget) + self.tabber.setObjectName("Tab windows") self.tabber.setTabsClosable(True) self.tabber.tabCloseRequested.connect(self.closeTab) + self.tabber.currentChanged.connect(self.changeTab) # add close action to tabs self.createToolbar() - mainLayout.addLayout(self.toolbar, 0, 0, -1, 1) + mainLayout.addWidget(self.toolbar, 0, 0, -1, 1) mainLayout.addWidget(self.tabber, 0, 2, -1, 10) self.mainWidget.setLayout(mainLayout) self.setCentralWidget(self.mainWidget) + def changeTab(self, currentIndex): + activeTab = self.tabber.widget(currentIndex) + self.sizeComboBox.setCurrentIndex(int(activeTab._canvasSize[1])) + self.ppiComboBox.setCurrentIndex(ppiList.index(str(activeTab._ppi))) + def closeTab(self, currentIndex): #todo add save alert self.tabber.widget(currentIndex).deleteLater() self.tabber.removeTab(currentIndex) def createToolbar(self): - self.toolbar = QFormLayout(self.mainWidget) - sizeComboBox = QComboBox() - sizeComboBox.addItems([f'A{i}' for i in range(5)]) - # sizeComboBox.activated[str].connect(lambda: self.tabber.currentWidget().setCanvasSize) - sizeComboBox.activated[str].connect(self.setCanvasSize) + self.toolbar = QWidget(self.mainWidget) + self.toolbar.setObjectName("Toolbar") + toolbarLayout = QFormLayout(self.toolbar) + self.sizeComboBox = QComboBox() + self.sizeComboBox.addItems(sheetDimensionList) + self.sizeComboBox.activated[str].connect(self.setCanvasSize) sizeLabel = QLabel("Canvas Size") - sizeLabel.setBuddy(sizeComboBox) - self.toolbar.setWidget(0, QFormLayout.LabelRole, sizeLabel) - self.toolbar.setWidget(0, QFormLayout.FieldRole, sizeComboBox) + sizeLabel.setBuddy(self.sizeComboBox) + toolbarLayout.setWidget(0, QFormLayout.LabelRole, sizeLabel) + toolbarLayout.setWidget(0, QFormLayout.FieldRole, self.sizeComboBox) - ppiComboBox = QComboBox() - ppiComboBox.addItems(["72", "96", "150", "300"]) - # ppiComboBox.activated[str].connect(lambda: self.tabber.currentWidget().setCanvasPPI) - ppiComboBox.activated[str].connect(self.setCanvasPPI) + self.ppiComboBox = QComboBox() + self.ppiComboBox.addItems(ppiList) + self.ppiComboBox.activated[str].connect(self.setCanvasPPI) ppiLabel = QLabel("Canvas ppi") - ppiLabel.setBuddy(ppiComboBox) - self.toolbar.setWidget(1, QFormLayout.LabelRole, ppiLabel) - self.toolbar.setWidget(1, QFormLayout.FieldRole, ppiComboBox) + ppiLabel.setBuddy(self.ppiComboBox) + toolbarLayout.setWidget(1, QFormLayout.LabelRole, ppiLabel) + toolbarLayout.setWidget(1, QFormLayout.FieldRole, self.ppiComboBox) + self.toolbar.setLayout(toolbarLayout) def setCanvasSize(self, size): self._defaultCanvasSize = size @@ -76,12 +89,21 @@ class appWindow(QMainWindow): activeCanvas.ppi = ppi def newDiagram(self): - diagram = canvas(size = self._defaultCanvasSize, ppi = self._defaultPPI) + diagram = canvas(size = self.sizeComboBox.currentIndex(), ppi = self.ppiComboBox.currentIndex()) + diagram.setObjectName("New") self.tabber.addTab(diagram, "New") - def saveImage(self): + def openDiagram(self): pass + def saveDiagram(self): + pass + + def saveImage(self): + # activeDiagram = QGraphicsScene() + activeDiagram = self.tabber.currentWidget() + activeDiagram.painter.addEllipse(10, 10, 100, 100) + def generateReport(self): pass diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 258d901..a01092c 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -1,15 +1,14 @@ from PyQt5.QtCore import Qt from PyQt5.QtGui import QBrush from PyQt5.QtWidgets import QWidget, QGraphicsScene, QGraphicsView, QHBoxLayout -from .sizes import paperSizes +from .sizes import paperSizes, sheetDimensionList, ppiList class canvas(QWidget): - def __init__(self, parent=None, size= "A0", ppi= 72): + def __init__(self, parent=None, size= 0, ppi= 1): super(canvas, self).__init__(parent) - self._ppi = ppi - self._canvasSize = size + self._ppi = ppiList[ppi] + self._canvasSize = sheetDimensionList[size] self.resize(1280, 720) - self.painter = QGraphicsScene(0, 0, *paperSizes[self.canvasSize][self.ppi]) self.painter.setBackgroundBrush(QBrush(Qt.white)) @@ -36,11 +35,9 @@ class canvas(QWidget): self._canvasSize = size if self.painter: self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) - # print(*paperSizes[self.canvasSize][self.ppi]) @ppi.setter def ppi(self, ppi): - self._ppi = int(ppi) + self._ppi = ppi if self.painter: - self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) - # print(*paperSizes[self.canvasSize][self.ppi]) \ No newline at end of file + self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) \ No newline at end of file diff --git a/src/main/python/utils/sizes.py b/src/main/python/utils/sizes.py index fc444cf..4d0686b 100644 --- a/src/main/python/utils/sizes.py +++ b/src/main/python/utils/sizes.py @@ -1,32 +1,36 @@ paperSizes = { "A0": { - 72: {2384, 3370}, - 96: {3179, 4494}, - 150: {4967, 7022}, - 300: {9933, 14043} + "72": {2384, 3370}, + "96": {3179, 4494}, + "150": {4967, 7022}, + "300": {9933, 14043} }, "A1": { - 72: {1684, 2384}, - 96: {2245, 3179}, - 150: {3508, 4967}, - 300: {7016, 9933} + "72": {1684, 2384}, + "96": {2245, 3179}, + "150": {3508, 4967}, + "300": {7016, 9933} }, "A2": { - 72: {1191, 1684}, - 96: {1587, 2245}, - 150: {2480, 3508}, - 300: {4960, 7016} + "72": {1191, 1684}, + "96": {1587, 2245}, + "150": {2480, 3508}, + "300": {4960, 7016} }, "A3": { - 72: {842, 1191}, - 96: {1123, 1587}, - 150: {1754, 2480}, - 300: {3508, 4960} + "72": {842, 1191}, + "96": {1123, 1587}, + "150": {1754, 2480}, + "300": {3508, 4960} }, "A4": { - 72: {595, 842}, - 96: {794, 1123}, - 150: {1240, 1754}, - 300: {2480, 3508} + "72": {595, 842}, + "96": {794, 1123}, + "150": {1240, 1754}, + "300": {2480, 3508} } -} \ No newline at end of file +} + +sheetDimensionList = [f'A{i}' for i in range(5)] + +ppiList = ["72", "96", "150", "300"] \ No newline at end of file -- cgit From a5043df3e40ca56823ed6bbfe5085331b80dde47 Mon Sep 17 00:00:00 2001 From: Blaine Date: Wed, 22 Apr 2020 13:28:05 +0530 Subject: imports sorted --- src/main/python/main.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index ebc80a2..41eafb0 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -1,14 +1,17 @@ +import pickle +import sys + from fbs_runtime.application_context.PyQt5 import ApplicationContext -from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot, QObject -from PyQt5.QtGui import (QBrush, QColor, QImage, QPainter, - QPalette) -from PyQt5.QtWidgets import (QWidget, QComboBox, QMainWindow, QGraphicsScene, - QGraphicsView, QGridLayout, QHBoxLayout, QLabel, - QPushButton, QMenuBar, QMenu, QFormLayout, QTabWidget) +from PyQt5.QtCore import QObject, Qt, pyqtSignal, pyqtSlot +from PyQt5.QtGui import QBrush, QColor, QImage, QPainter, QPalette +from PyQt5.QtWidgets import (QComboBox, QFileDialog, QFormLayout, + QGraphicsScene, QGraphicsView, QGridLayout, + QHBoxLayout, QLabel, QMainWindow, QMenu, QMenuBar, + QPushButton, QTabWidget, QWidget) from utils.canvas import canvas -from utils.sizes import sheetDimensionList, ppiList -import sys +from utils.sizes import ppiList, sheetDimensionList + class appWindow(QMainWindow): def __init__(self, parent=None): @@ -97,7 +100,10 @@ class appWindow(QMainWindow): pass def saveDiagram(self): - pass + name = QFileDialog.getSaveFileName(self, 'Save File', 'New Diagram', 'Process Flow Diagram (*.pfd)') + with open(name[0],'w') as file: + for i in range(self.tabber.count()): + file.write(self.tabber.widget(i)) def saveImage(self): # activeDiagram = QGraphicsScene() @@ -112,4 +118,4 @@ if __name__ == '__main__': test = appWindow() test.show() exit_code = app.app.exec_() # 2. Invoke appctxt.app.exec_() - sys.exit(exit_code) \ No newline at end of file + sys.exit(exit_code) -- cgit From 8713e4293b7297e2f0d96c9439e870fbd934e975 Mon Sep 17 00:00:00 2001 From: Blaine Date: Wed, 22 Apr 2020 16:05:50 +0530 Subject: Add save and load feature --- src/main/python/main.py | 47 ++++++++++++++++++++++++++++----------- src/main/python/utils/canvas.py | 45 ++++++++++++++++++++++++++++++++----- src/main/python/utils/graphics.py | 1 + 3 files changed, 74 insertions(+), 19 deletions(-) create mode 100644 src/main/python/utils/graphics.py (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 41eafb0..7f7c44a 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -32,26 +32,35 @@ class appWindow(QMainWindow): self.menuGenerate.addAction("Image", self.saveImage) self.menuGenerate.addAction("Report", self.generateReport) - mainLayout = QGridLayout(self.mainWidget) + # mainLayout = QGridLayout(self.mainWidget) + mainLayout = QHBoxLayout(self.mainWidget) mainLayout.setObjectName("Main Layout") + #Implement tabs self.tabber = QTabWidget(self.mainWidget) self.tabber.setObjectName("Tab windows") self.tabber.setTabsClosable(True) self.tabber.tabCloseRequested.connect(self.closeTab) self.tabber.currentChanged.connect(self.changeTab) # add close action to tabs - self.createToolbar() - mainLayout.addWidget(self.toolbar, 0, 0, -1, 1) - mainLayout.addWidget(self.tabber, 0, 2, -1, 10) + + self.createToolbar() + # mainLayout.addWidget(self.toolbar, 0, 0, -1, 1) + # mainLayout.addWidget(self.tabber, 0, 2, -1, 6) + mainLayout.addWidget(self.toolbar) + mainLayout.addWidget(self.tabber) + #declare main window layout self.mainWidget.setLayout(mainLayout) self.setCentralWidget(self.mainWidget) def changeTab(self, currentIndex): activeTab = self.tabber.widget(currentIndex) - self.sizeComboBox.setCurrentIndex(int(activeTab._canvasSize[1])) - self.ppiComboBox.setCurrentIndex(ppiList.index(str(activeTab._ppi))) + if activeTab: + self.sizeComboBox.setCurrentIndex(sheetDimensionList.index(activeTab._canvasSize)) + self.ppiComboBox.setCurrentIndex(ppiList.index(str(activeTab._ppi))) + print(activeTab.dimensions) + self.tabber.resize(*activeTab.dimensions) def closeTab(self, currentIndex): #todo add save alert @@ -61,6 +70,7 @@ class appWindow(QMainWindow): def createToolbar(self): self.toolbar = QWidget(self.mainWidget) self.toolbar.setObjectName("Toolbar") + self.toolbar.setFixedWidth(200) toolbarLayout = QFormLayout(self.toolbar) self.sizeComboBox = QComboBox() self.sizeComboBox.addItems(sheetDimensionList) @@ -84,31 +94,42 @@ class appWindow(QMainWindow): activeCanvas = self.tabber.currentWidget() if activeCanvas: activeCanvas.canvasSize = size + self.tabber.resize(*activeCanvas.dimensions) def setCanvasPPI(self, ppi): self._defaultPPI = ppi activeCanvas = self.tabber.currentWidget() if activeCanvas: activeCanvas.ppi = ppi + self.tabber.resize(*activeCanvas.dimensions) def newDiagram(self): diagram = canvas(size = self.sizeComboBox.currentIndex(), ppi = self.ppiComboBox.currentIndex()) diagram.setObjectName("New") + self.tabber.resize(*diagram.dimensions) self.tabber.addTab(diagram, "New") def openDiagram(self): - pass + name = QFileDialog.getOpenFileNames(self, 'Open File(s)', '', 'Process Flow Diagram (*pfd)') + if name: + tabs = [] + for files in name[0]: + with open(files,'rb') as file: + tabs += pickle.load(file) + for i in tabs: + self.tabber.addTab(i, i.objectName()) def saveDiagram(self): name = QFileDialog.getSaveFileName(self, 'Save File', 'New Diagram', 'Process Flow Diagram (*.pfd)') - with open(name[0],'w') as file: - for i in range(self.tabber.count()): - file.write(self.tabber.widget(i)) + if name: + with open(name[0],'wb') as file: + tabs = [] + for i in range(self.tabber.count()): + tabs.append(self.tabber.widget(i)) + pickle.dump(tabs, file) def saveImage(self): - # activeDiagram = QGraphicsScene() - activeDiagram = self.tabber.currentWidget() - activeDiagram.painter.addEllipse(10, 10, 100, 100) + pass def generateReport(self): pass diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index a01092c..c101422 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -1,18 +1,24 @@ from PyQt5.QtCore import Qt from PyQt5.QtGui import QBrush -from PyQt5.QtWidgets import QWidget, QGraphicsScene, QGraphicsView, QHBoxLayout -from .sizes import paperSizes, sheetDimensionList, ppiList +from PyQt5.QtWidgets import QGraphicsScene, QGraphicsView, QHBoxLayout, QWidget + +import graphics +from .sizes import paperSizes, ppiList, sheetDimensionList + + class canvas(QWidget): def __init__(self, parent=None, size= 0, ppi= 1): super(canvas, self).__init__(parent) self._ppi = ppiList[ppi] - self._canvasSize = sheetDimensionList[size] - self.resize(1280, 720) - + self._canvasSize = sheetDimensionList[size] self.painter = QGraphicsScene(0, 0, *paperSizes[self.canvasSize][self.ppi]) + self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) + self.setMaximumSize(*paperSizes[self.canvasSize][self.ppi]) + self.resize(*paperSizes[self.canvasSize][self.ppi]) self.painter.setBackgroundBrush(QBrush(Qt.white)) self.view = QGraphicsView(self.painter) + self.view.setMaximumSize(794, 1123) self.layout = QHBoxLayout(self) self.layout.addWidget(self.view) self.setLayout(self.layout) @@ -35,9 +41,36 @@ class canvas(QWidget): self._canvasSize = size if self.painter: self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) + self.setMaximumSize(*paperSizes[self.canvasSize][self.ppi]) + self.resize(*paperSizes[self.canvasSize][self.ppi]) + @ppi.setter def ppi(self, ppi): self._ppi = ppi if self.painter: - self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) \ No newline at end of file + self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) + self.setMaximumSize(*paperSizes[self.canvasSize][self.ppi]) + self.resize(*paperSizes[self.canvasSize][self.ppi]) + + @property + def dimensions(self): + return self.painter.sceneRect().width(), self.painter.sceneRect().height() + + def __getstate__(self) -> dict: + return { + "_classname_": self.__class__.__name__, + "ppi": self._ppi, + "canvasSize": self._canvasSize, + "ObjectName": self.objectName(), + "items": [i.__getState__() for i in self.painter.items()] + } + + def __setstate__(self, dict): + self.__init__() + self._ppi = dict['ppi'] + self._canvasSize = dict['canvasSize'] + self.setObjectName(dict['ObjectName']) + for item in dict['items']: + graphic = getattr(graphics, dict['_classname_']) + self.painter.addItem(item) diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py new file mode 100644 index 0000000..fc80254 --- /dev/null +++ b/src/main/python/utils/graphics.py @@ -0,0 +1 @@ +pass \ No newline at end of file -- cgit From a8a5b967e329a2ef5688089e8cbec2e37835fc08 Mon Sep 17 00:00:00 2001 From: Blaine Date: Wed, 22 Apr 2020 16:09:24 +0530 Subject: small tidying --- src/main/python/utils/sizes.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/sizes.py b/src/main/python/utils/sizes.py index 4d0686b..f1a56b3 100644 --- a/src/main/python/utils/sizes.py +++ b/src/main/python/utils/sizes.py @@ -31,6 +31,5 @@ paperSizes = { } } -sheetDimensionList = [f'A{i}' for i in range(5)] - +sheetDimensionList = paperSizes.keys() ppiList = ["72", "96", "150", "300"] \ No newline at end of file -- cgit From 29d9ce50dd43a855453a16008cf8bcf2a17c3ec8 Mon Sep 17 00:00:00 2001 From: Blaine Date: Wed, 22 Apr 2020 16:15:06 +0530 Subject: save feature for canvas items --- src/main/python/utils/canvas.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index c101422..6f0fb23 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -73,4 +73,5 @@ class canvas(QWidget): self.setObjectName(dict['ObjectName']) for item in dict['items']: graphic = getattr(graphics, dict['_classname_']) - self.painter.addItem(item) + graphic.setstate(item) + self.painter.addItem(graphic) -- cgit From 1d2b1cec812101d941907c1a2976a74439e67afa Mon Sep 17 00:00:00 2001 From: Blaine Date: Wed, 22 Apr 2020 16:42:25 +0530 Subject: Fixed Broken Imports --- src/main/python/main.py | 2 +- src/main/python/utils/canvas.py | 2 +- src/main/python/utils/sizes.py | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 7f7c44a..79fb2c6 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -16,7 +16,7 @@ from utils.sizes import ppiList, sheetDimensionList class appWindow(QMainWindow): def __init__(self, parent=None): super(appWindow, self).__init__(parent) - self.resize(1280, 720) + # self.resize(1280, 720) self._defaultPPI = 72 self._defaultCanvasSize = "A0" diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 6f0fb23..49c0bdb 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -2,7 +2,7 @@ from PyQt5.QtCore import Qt from PyQt5.QtGui import QBrush from PyQt5.QtWidgets import QGraphicsScene, QGraphicsView, QHBoxLayout, QWidget -import graphics +from . import graphics from .sizes import paperSizes, ppiList, sheetDimensionList diff --git a/src/main/python/utils/sizes.py b/src/main/python/utils/sizes.py index f1a56b3..4d0686b 100644 --- a/src/main/python/utils/sizes.py +++ b/src/main/python/utils/sizes.py @@ -31,5 +31,6 @@ paperSizes = { } } -sheetDimensionList = paperSizes.keys() +sheetDimensionList = [f'A{i}' for i in range(5)] + ppiList = ["72", "96", "150", "300"] \ No newline at end of file -- cgit From 031cf7132bb1d622e8b49cfa9cbc5d1918869c21 Mon Sep 17 00:00:00 2001 From: Blaine Date: Thu, 23 Apr 2020 14:52:57 +0530 Subject: Added tabs and extended save feature --- src/main/python/main.py | 81 +++++++++++----------------- src/main/python/utils/canvas.py | 116 +++++++++++++++++++++++++++++++++++----- src/main/python/utils/sizes.py | 40 +++++++------- 3 files changed, 154 insertions(+), 83 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 79fb2c6..23c01e8 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -7,27 +7,28 @@ from PyQt5.QtGui import QBrush, QColor, QImage, QPainter, QPalette from PyQt5.QtWidgets import (QComboBox, QFileDialog, QFormLayout, QGraphicsScene, QGraphicsView, QGridLayout, QHBoxLayout, QLabel, QMainWindow, QMenu, QMenuBar, - QPushButton, QTabWidget, QWidget) + QPushButton, QTabWidget, QWidget, QMdiArea) -from utils.canvas import canvas +from utils.canvas import canvas, fileWindow from utils.sizes import ppiList, sheetDimensionList class appWindow(QMainWindow): def __init__(self, parent=None): super(appWindow, self).__init__(parent) - # self.resize(1280, 720) + self.resize(1280, 720) + # self.setWindowState(Qt.WindowMaximized) self._defaultPPI = 72 - self._defaultCanvasSize = "A0" + self._defaultCanvasSize = "A4" titleMenu = self.menuBar() self.mainWidget = QWidget(self) self.mainWidget.setObjectName("Main Widget") self.menuFile = titleMenu.addMenu('File') #File Menu - self.menuFile.addAction("New", self.newDiagram) - self.menuFile.addAction("Open", self.openDiagram) - self.menuFile.addAction("Save", self.saveDiagram) + self.menuFile.addAction("New", self.newProject) + self.menuFile.addAction("Open", self.openProject) + self.menuFile.addAction("Save", self.saveProject) self.menuGenerate = titleMenu.addMenu('Generate') #Generate menu self.menuGenerate.addAction("Image", self.saveImage) self.menuGenerate.addAction("Report", self.generateReport) @@ -36,36 +37,18 @@ class appWindow(QMainWindow): mainLayout = QHBoxLayout(self.mainWidget) mainLayout.setObjectName("Main Layout") - #Implement tabs - self.tabber = QTabWidget(self.mainWidget) - self.tabber.setObjectName("Tab windows") - self.tabber.setTabsClosable(True) - self.tabber.tabCloseRequested.connect(self.closeTab) - self.tabber.currentChanged.connect(self.changeTab) + #ImpsaveProject + self.mdi = QMdiArea(self) + # self.mdi.closeEvent().connect(self.closeProject) # add close action to tabs self.createToolbar() - # mainLayout.addWidget(self.toolbar, 0, 0, -1, 1) - # mainLayout.addWidget(self.tabber, 0, 2, -1, 6) mainLayout.addWidget(self.toolbar) - mainLayout.addWidget(self.tabber) + mainLayout.addWidget(self.mdi) #declare main window layout self.mainWidget.setLayout(mainLayout) self.setCentralWidget(self.mainWidget) - - def changeTab(self, currentIndex): - activeTab = self.tabber.widget(currentIndex) - if activeTab: - self.sizeComboBox.setCurrentIndex(sheetDimensionList.index(activeTab._canvasSize)) - self.ppiComboBox.setCurrentIndex(ppiList.index(str(activeTab._ppi))) - print(activeTab.dimensions) - self.tabber.resize(*activeTab.dimensions) - - def closeTab(self, currentIndex): - #todo add save alert - self.tabber.widget(currentIndex).deleteLater() - self.tabber.removeTab(currentIndex) def createToolbar(self): self.toolbar = QWidget(self.mainWidget) @@ -74,6 +57,7 @@ class appWindow(QMainWindow): toolbarLayout = QFormLayout(self.toolbar) self.sizeComboBox = QComboBox() self.sizeComboBox.addItems(sheetDimensionList) + self.sizeComboBox.setCurrentIndex(4) self.sizeComboBox.activated[str].connect(self.setCanvasSize) sizeLabel = QLabel("Canvas Size") sizeLabel.setBuddy(self.sizeComboBox) @@ -94,39 +78,38 @@ class appWindow(QMainWindow): activeCanvas = self.tabber.currentWidget() if activeCanvas: activeCanvas.canvasSize = size - self.tabber.resize(*activeCanvas.dimensions) + # self.tabber.resize(*activeCanvas.dimensions) + print(activeCanvas.dimensions) def setCanvasPPI(self, ppi): self._defaultPPI = ppi activeCanvas = self.tabber.currentWidget() if activeCanvas: activeCanvas.ppi = ppi - self.tabber.resize(*activeCanvas.dimensions) + # self.tabber.resize(*activeCanvas.dimensions) - def newDiagram(self): - diagram = canvas(size = self.sizeComboBox.currentIndex(), ppi = self.ppiComboBox.currentIndex()) - diagram.setObjectName("New") - self.tabber.resize(*diagram.dimensions) - self.tabber.addTab(diagram, "New") + def newProject(self): + project = fileWindow(self.mdi) + project.setObjectName("New Project") + self.mdi.addSubWindow(project) + if not project.tabList: + project.newDiagram() + project.show() - def openDiagram(self): + def openProject(self): name = QFileDialog.getOpenFileNames(self, 'Open File(s)', '', 'Process Flow Diagram (*pfd)') if name: - tabs = [] for files in name[0]: with open(files,'rb') as file: - tabs += pickle.load(file) - for i in tabs: - self.tabber.addTab(i, i.objectName()) + project = pickle.load(file) + self.mdi.addSubWindow(project) + project.show() - def saveDiagram(self): - name = QFileDialog.getSaveFileName(self, 'Save File', 'New Diagram', 'Process Flow Diagram (*.pfd)') - if name: - with open(name[0],'wb') as file: - tabs = [] - for i in range(self.tabber.count()): - tabs.append(self.tabber.widget(i)) - pickle.dump(tabs, file) + def saveProject(self): + for j, i in enumerate(self.mdi.subWindowList()): + if i.tabCount: + name = QFileDialog.getSaveFileName(self, 'Save File', f'New Diagram {j}', 'Process Flow Diagram (*.pfd)') + i.saveProject(name) def saveImage(self): pass diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 49c0bdb..4a1ec6b 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -1,26 +1,33 @@ +import pickle + from PyQt5.QtCore import Qt from PyQt5.QtGui import QBrush -from PyQt5.QtWidgets import QGraphicsScene, QGraphicsView, QHBoxLayout, QWidget +from PyQt5.QtWidgets import (QFileDialog, QGraphicsScene, QGraphicsView, + QHBoxLayout, QMainWindow, QMdiSubWindow, + QMessageBox, QTabWidget, QWidget, QMenuBar, QVBoxLayout) from . import graphics from .sizes import paperSizes, ppiList, sheetDimensionList class canvas(QWidget): - def __init__(self, parent=None, size= 0, ppi= 1): + def __init__(self, parent=None, size= 4, ppi= 1): super(canvas, self).__init__(parent) self._ppi = ppiList[ppi] - self._canvasSize = sheetDimensionList[size] - self.painter = QGraphicsScene(0, 0, *paperSizes[self.canvasSize][self.ppi]) + self._canvasSize = sheetDimensionList[size] + + self.painter = QGraphicsScene() self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) - self.setMaximumSize(*paperSizes[self.canvasSize][self.ppi]) - self.resize(*paperSizes[self.canvasSize][self.ppi]) + self.painter.setBackgroundBrush(QBrush(Qt.white)) + self.view = QGraphicsView(self.painter) - self.view.setMaximumSize(794, 1123) + self.view.setMinimumSize(595, 842) + self.view.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) + self.layout = QHBoxLayout(self) - self.layout.addWidget(self.view) + self.layout.addWidget(self.view) self.setLayout(self.layout) def setCanvasSize(self, size): @@ -41,17 +48,14 @@ class canvas(QWidget): self._canvasSize = size if self.painter: self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) - self.setMaximumSize(*paperSizes[self.canvasSize][self.ppi]) - self.resize(*paperSizes[self.canvasSize][self.ppi]) - + self.view.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) @ppi.setter def ppi(self, ppi): self._ppi = ppi if self.painter: self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) - self.setMaximumSize(*paperSizes[self.canvasSize][self.ppi]) - self.resize(*paperSizes[self.canvasSize][self.ppi]) + self.view.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) @property def dimensions(self): @@ -73,5 +77,89 @@ class canvas(QWidget): self.setObjectName(dict['ObjectName']) for item in dict['items']: graphic = getattr(graphics, dict['_classname_']) - graphic.setstate(item) + graphic.__setstate__(item) self.painter.addItem(graphic) + +class fileWindow(QMdiSubWindow): + def __init__(self, parent = None, title = 'New Project'): + super(fileWindow, self).__init__(parent) + + self.widget = QWidget(self) + layout = QVBoxLayout(self.widget) + + self.tabber = QTabWidget(self.widget) + self.tabber.setObjectName(title) + self.tabber.setTabsClosable(True) + self.tabber.tabCloseRequested.connect(self.closeTab) + self.tabber.currentChanged.connect(self.changeTab) + layout.addWidget(self.tabber) + + titleMenu = QMenuBar(self) + menuFile = titleMenu.addMenu('File') #File Menu + menuFile.addAction("New", self.newDiagram) + layout.setMenuBar(titleMenu) + + self.widget.setLayout(layout) + self.setWidget(self.widget) + self.setWindowTitle(title) + + def changeTab(self, currentIndex): + pass + + def closeTab(self, currentIndex): + if self.saveEvent(): + self.tabber.widget(currentIndex).deleteLater() + self.tabber.removeTab(currentIndex) + + def newDiagram(self): + diagram = canvas() + diagram.setObjectName("New") + self.tabber.addTab(diagram, "New") + + @property + def tabList(self): + return [self.tabber.widget(i) for i in range(self.tabCount)] + + @property + def tabCount(self): + return self.tabber.count() + + def __getstate__(self) -> dict: + return { + "_classname_": self.__class__.__name__, + "ObjectName": self.objectName(), + "tabs": [i.__getstate__() for i in self.tabList] + } + + def __setstate__(self, dict): + self.__init__(title = dict['ObjectName']) + for i in dict['tabs']: + diagram = canvas() + diagram.__setstate__(i) + self.tabber.addTab(diagram, i['ObjectName']) + + def saveProject(self, name = None): + name = QFileDialog.getSaveFileName(self, 'Save File', f'New Diagram', 'Process Flow Diagram (*.pfd)') if not name else name + if name: + with open(name[0],'wb') as file: + pickle.dump(self, file) + return True + else: + return False + + def closeEvent(self, event): + if self.saveEvent(): + event.accept() + else: + event.ignore() + # super(fileWindow, self).closeEvent(event) + def saveEvent(self): + alert = QMessageBox.question(self, self.objectName(), "All unsaved progress will be LOST!", + QMessageBox.StandardButtons(QMessageBox.Save|QMessageBox.Ignore|QMessageBox.Cancel), QMessageBox.Save) + if alert == QMessageBox.Cancel: + return False + else: + if alert == QMessageBox.Save: + if not self.saveProject(): + return False + return True \ No newline at end of file diff --git a/src/main/python/utils/sizes.py b/src/main/python/utils/sizes.py index 4d0686b..b0aa70a 100644 --- a/src/main/python/utils/sizes.py +++ b/src/main/python/utils/sizes.py @@ -1,33 +1,33 @@ paperSizes = { "A0": { - "72": {2384, 3370}, - "96": {3179, 4494}, - "150": {4967, 7022}, - "300": {9933, 14043} + "72": [2384, 3370], + "96": [3179, 4494], + "150": [4967, 7022], + "300": [9933, 14043] }, "A1": { - "72": {1684, 2384}, - "96": {2245, 3179}, - "150": {3508, 4967}, - "300": {7016, 9933} + "72": [1684, 2384], + "96": [2245, 3179], + "150": [3508, 4967], + "300": [7016, 9933] }, "A2": { - "72": {1191, 1684}, - "96": {1587, 2245}, - "150": {2480, 3508}, - "300": {4960, 7016} + "72": [1191, 1684], + "96": [1587, 2245], + "150": [2480, 3508], + "300": [4960, 7016] }, "A3": { - "72": {842, 1191}, - "96": {1123, 1587}, - "150": {1754, 2480}, - "300": {3508, 4960} + "72": [842, 1191], + "96": [1123, 1587], + "150": [1754, 2480], + "300": [3508, 4960] }, "A4": { - "72": {595, 842}, - "96": {794, 1123}, - "150": {1240, 1754}, - "300": {2480, 3508} + "72": [595, 842], + "96": [794, 1123], + "150": [1240, 1754], + "300": [2480, 3508] } } -- cgit From 38568178ac8541700ca19cf73843fc3f1b2a928f Mon Sep 17 00:00:00 2001 From: Blaine Date: Thu, 23 Apr 2020 15:17:26 +0530 Subject: implement save Window on main window --- src/main/python/main.py | 36 ++++++++++++++++++++++++++++++------ src/main/python/utils/canvas.py | 27 +++++++++++++++++++-------- 2 files changed, 49 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 23c01e8..7ae9d63 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -7,7 +7,7 @@ from PyQt5.QtGui import QBrush, QColor, QImage, QPainter, QPalette from PyQt5.QtWidgets import (QComboBox, QFileDialog, QFormLayout, QGraphicsScene, QGraphicsView, QGridLayout, QHBoxLayout, QLabel, QMainWindow, QMenu, QMenuBar, - QPushButton, QTabWidget, QWidget, QMdiArea) + QPushButton, QTabWidget, QWidget, QMdiArea, QMessageBox) from utils.canvas import canvas, fileWindow from utils.sizes import ppiList, sheetDimensionList @@ -39,10 +39,8 @@ class appWindow(QMainWindow): #ImpsaveProject self.mdi = QMdiArea(self) - # self.mdi.closeEvent().connect(self.closeProject) # add close action to tabs - self.createToolbar() mainLayout.addWidget(self.toolbar) mainLayout.addWidget(self.mdi) @@ -75,7 +73,8 @@ class appWindow(QMainWindow): def setCanvasSize(self, size): self._defaultCanvasSize = size - activeCanvas = self.tabber.currentWidget() + activeCanvas = self.mdi.currentSubWindow() + activeCanvas._defaultCanvasSize = size if activeCanvas: activeCanvas.canvasSize = size # self.tabber.resize(*activeCanvas.dimensions) @@ -83,18 +82,20 @@ class appWindow(QMainWindow): def setCanvasPPI(self, ppi): self._defaultPPI = ppi - activeCanvas = self.tabber.currentWidget() + activeCanvas = self.mdi.currentSubWindow() + activeCanvas._defaultPPI = ppi if activeCanvas: activeCanvas.ppi = ppi # self.tabber.resize(*activeCanvas.dimensions) def newProject(self): - project = fileWindow(self.mdi) + project = fileWindow(self.mdi, size = self._defaultCanvasSize, ppi = self._defaultPPI) project.setObjectName("New Project") self.mdi.addSubWindow(project) if not project.tabList: project.newDiagram() project.show() + project.resizeHandler(self.mdi) def openProject(self): name = QFileDialog.getOpenFileNames(self, 'Open File(s)', '', 'Process Flow Diagram (*pfd)') @@ -104,6 +105,8 @@ class appWindow(QMainWindow): project = pickle.load(file) self.mdi.addSubWindow(project) project.show() + project.resizeHandler(self.mdi) + def saveProject(self): for j, i in enumerate(self.mdi.subWindowList()): @@ -116,6 +119,27 @@ class appWindow(QMainWindow): def generateReport(self): pass + + def resizeEvent(self, event): + self.mdi.activeSubWindow().resizeHandler(self.mdi) + super(appWindow, self).resizeEvent(event) + + def closeEvent(self, event): + if self.saveEvent(): + event.accept() + else: + event.ignore() + + def saveEvent(self, event): + alert = QMessageBox.question(self, self.objectName(), "All unsaved progress will be LOST!", + QMessageBox.StandardButtons(QMessageBox.Save|QMessageBox.Ignore|QMessageBox.Cancel), QMessageBox.Save) + if alert == QMessageBox.Cancel: + return False + else: + if alert == QMessageBox.Save: + if not self.saveProject(): + return False + return True if __name__ == '__main__': app = ApplicationContext() # 1. Instantiate ApplicationContext diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 4a1ec6b..2e2e0d9 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -4,7 +4,7 @@ from PyQt5.QtCore import Qt from PyQt5.QtGui import QBrush from PyQt5.QtWidgets import (QFileDialog, QGraphicsScene, QGraphicsView, QHBoxLayout, QMainWindow, QMdiSubWindow, - QMessageBox, QTabWidget, QWidget, QMenuBar, QVBoxLayout) + QMessageBox, QTabWidget, QWidget, QMenuBar, QHBoxLayout) from . import graphics from .sizes import paperSizes, ppiList, sheetDimensionList @@ -81,11 +81,13 @@ class canvas(QWidget): self.painter.addItem(graphic) class fileWindow(QMdiSubWindow): - def __init__(self, parent = None, title = 'New Project'): + def __init__(self, parent = None, title = 'New Project', size = 4, ppi = 1): super(fileWindow, self).__init__(parent) + self._ppi = ppiList[ppi] + self._canvasSize = sheetDimensionList[size] self.widget = QWidget(self) - layout = QVBoxLayout(self.widget) + layout = QHBoxLayout(self.widget) self.tabber = QTabWidget(self.widget) self.tabber.setObjectName(title) @@ -98,11 +100,10 @@ class fileWindow(QMdiSubWindow): menuFile = titleMenu.addMenu('File') #File Menu menuFile.addAction("New", self.newDiagram) layout.setMenuBar(titleMenu) - self.widget.setLayout(layout) self.setWidget(self.widget) self.setWindowTitle(title) - + def changeTab(self, currentIndex): pass @@ -112,10 +113,18 @@ class fileWindow(QMdiSubWindow): self.tabber.removeTab(currentIndex) def newDiagram(self): - diagram = canvas() + diagram = canvas(self.tabber, size = self._canvasSize, ppi = self._ppi) diagram.setObjectName("New") self.tabber.addTab(diagram, "New") + def resizeHandler(self, parent = None): + parentRect = parent.rect() if parent else self.parent().rect() + self.resize(parentRect().width(), parentRect().height()) + self.setMaximumHeight(parentRect().height()) + self.tabber.setMaximumHeight(parentRect().height()) + for i in self.tabList: + i.setMaximumHeight(parentRect().height()) + @property def tabList(self): return [self.tabber.widget(i) for i in range(self.tabCount)] @@ -128,13 +137,15 @@ 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']) for i in dict['tabs']: - diagram = canvas() + diagram = canvas(self.tabber, size = dict['canvasSize'], ppi = dict['ppi']) diagram.__setstate__(i) self.tabber.addTab(diagram, i['ObjectName']) @@ -152,7 +163,7 @@ class fileWindow(QMdiSubWindow): event.accept() else: event.ignore() - # super(fileWindow, self).closeEvent(event) + def saveEvent(self): alert = QMessageBox.question(self, self.objectName(), "All unsaved progress will be LOST!", QMessageBox.StandardButtons(QMessageBox.Save|QMessageBox.Ignore|QMessageBox.Cancel), QMessageBox.Save) -- cgit From 9879d34bb984c7d4ef466c79472b3193275365b1 Mon Sep 17 00:00:00 2001 From: Blaine Date: Thu, 23 Apr 2020 15:35:49 +0530 Subject: can change canvas and ppi sizes --- src/main/python/main.py | 36 +++++++++++++++++------------------- src/main/python/utils/canvas.py | 34 ++++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 7ae9d63..8f11944 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -15,10 +15,9 @@ from utils.sizes import ppiList, sheetDimensionList class appWindow(QMainWindow): def __init__(self, parent=None): - super(appWindow, self).__init__(parent) - self.resize(1280, 720) + super(appWindow, self).__init__(parent) # self.setWindowState(Qt.WindowMaximized) - self._defaultPPI = 72 + self._defaultPPI = '72' self._defaultCanvasSize = "A4" titleMenu = self.menuBar() @@ -47,6 +46,7 @@ class appWindow(QMainWindow): #declare main window layout self.mainWidget.setLayout(mainLayout) self.setCentralWidget(self.mainWidget) + self.resize(1280, 720) def createToolbar(self): self.toolbar = QWidget(self.mainWidget) @@ -74,19 +74,14 @@ class appWindow(QMainWindow): def setCanvasSize(self, size): self._defaultCanvasSize = size activeCanvas = self.mdi.currentSubWindow() - activeCanvas._defaultCanvasSize = size if activeCanvas: activeCanvas.canvasSize = size - # self.tabber.resize(*activeCanvas.dimensions) - print(activeCanvas.dimensions) def setCanvasPPI(self, ppi): self._defaultPPI = ppi activeCanvas = self.mdi.currentSubWindow() - activeCanvas._defaultPPI = ppi if activeCanvas: - activeCanvas.ppi = ppi - # self.tabber.resize(*activeCanvas.dimensions) + activeCanvas.ppi = ppi def newProject(self): project = fileWindow(self.mdi, size = self._defaultCanvasSize, ppi = self._defaultPPI) @@ -121,7 +116,8 @@ class appWindow(QMainWindow): pass def resizeEvent(self, event): - self.mdi.activeSubWindow().resizeHandler(self.mdi) + if self.mdi.activeSubWindow(): + self.mdi.activeSubWindow().resizeHandler(self.mdi) super(appWindow, self).resizeEvent(event) def closeEvent(self, event): @@ -130,15 +126,17 @@ class appWindow(QMainWindow): else: event.ignore() - def saveEvent(self, event): - alert = QMessageBox.question(self, self.objectName(), "All unsaved progress will be LOST!", - QMessageBox.StandardButtons(QMessageBox.Save|QMessageBox.Ignore|QMessageBox.Cancel), QMessageBox.Save) - if alert == QMessageBox.Cancel: - return False - else: - if alert == QMessageBox.Save: - if not self.saveProject(): - return False + def saveEvent(self): + if self.mdi.subWindowList(): + alert = QMessageBox.question(self, self.objectName(), "All unsaved progress will be LOST!", + QMessageBox.StandardButtons(QMessageBox.Save|QMessageBox.Ignore|QMessageBox.Cancel), + QMessageBox.Save) + if alert == QMessageBox.Cancel: + return False + else: + if alert == QMessageBox.Save: + if not self.saveProject(): + return False return True if __name__ == '__main__': diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 2e2e0d9..2d840f6 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -11,11 +11,11 @@ from .sizes import paperSizes, ppiList, sheetDimensionList class canvas(QWidget): - def __init__(self, parent=None, size= 4, ppi= 1): + def __init__(self, parent=None, size= 'A4', ppi= '72'): super(canvas, self).__init__(parent) - self._ppi = ppiList[ppi] - self._canvasSize = sheetDimensionList[size] + self._ppi = ppi + self._canvasSize = size self.painter = QGraphicsScene() self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) @@ -81,11 +81,11 @@ class canvas(QWidget): self.painter.addItem(graphic) class fileWindow(QMdiSubWindow): - def __init__(self, parent = None, title = 'New Project', size = 4, ppi = 1): + def __init__(self, parent = None, title = 'New Project', size = 'A4', ppi = '72'): super(fileWindow, self).__init__(parent) - self._ppi = ppiList[ppi] - self._canvasSize = sheetDimensionList[size] + self._ppi = ppi + self._canvasSize = size self.widget = QWidget(self) layout = QHBoxLayout(self.widget) @@ -104,6 +104,28 @@ class fileWindow(QMdiSubWindow): self.setWidget(self.widget) self.setWindowTitle(title) + @property + def canvasSize(self): + return self._canvasSize + @property + def ppi(self): + return self._ppi + + @canvasSize.setter + def canvasSize(self, size): + self._canvasSize = sheetDimensionList.index(size) + if self.tabCount: + activeTab = self.tabber.currentWidget() + activeTab.canvasSize = size + + @ppi.setter + def ppi(self, ppi): + self._ppi = ppiList.index(ppi) + if self.tabCount: + activeTab = self.tabber.currentWidget() + activeTab.ppi = ppi + + def changeTab(self, currentIndex): pass -- cgit From f7ff2e807ff15b1a29093203f7e744810de94435 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 25 Apr 2020 08:09:13 +0530 Subject: implement new tab button, and context menu. --- src/main/python/main.py | 21 ++----------- src/main/python/utils/canvas.py | 65 +++++++++++++++++++++++++++++------------ src/main/python/utils/tabs.py | 51 ++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 37 deletions(-) create mode 100644 src/main/python/utils/tabs.py (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 8f11944..52a8a33 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -16,7 +16,6 @@ from utils.sizes import ppiList, sheetDimensionList class appWindow(QMainWindow): def __init__(self, parent=None): super(appWindow, self).__init__(parent) - # self.setWindowState(Qt.WindowMaximized) self._defaultPPI = '72' self._defaultCanvasSize = "A4" @@ -46,30 +45,16 @@ class appWindow(QMainWindow): #declare main window layout self.mainWidget.setLayout(mainLayout) self.setCentralWidget(self.mainWidget) - self.resize(1280, 720) + self.resize(1280, 720) + self.setWindowState(Qt.WindowMaximized) def createToolbar(self): self.toolbar = QWidget(self.mainWidget) self.toolbar.setObjectName("Toolbar") self.toolbar.setFixedWidth(200) toolbarLayout = QFormLayout(self.toolbar) - self.sizeComboBox = QComboBox() - self.sizeComboBox.addItems(sheetDimensionList) - self.sizeComboBox.setCurrentIndex(4) - self.sizeComboBox.activated[str].connect(self.setCanvasSize) - sizeLabel = QLabel("Canvas Size") - sizeLabel.setBuddy(self.sizeComboBox) - toolbarLayout.setWidget(0, QFormLayout.LabelRole, sizeLabel) - toolbarLayout.setWidget(0, QFormLayout.FieldRole, self.sizeComboBox) - - self.ppiComboBox = QComboBox() - self.ppiComboBox.addItems(ppiList) - self.ppiComboBox.activated[str].connect(self.setCanvasPPI) - ppiLabel = QLabel("Canvas ppi") - ppiLabel.setBuddy(self.ppiComboBox) - toolbarLayout.setWidget(1, QFormLayout.LabelRole, ppiLabel) - toolbarLayout.setWidget(1, QFormLayout.FieldRole, self.ppiComboBox) self.toolbar.setLayout(toolbarLayout) + def setCanvasSize(self, size): self._defaultCanvasSize = size diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 2d840f6..9578b1a 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -2,12 +2,14 @@ import pickle from PyQt5.QtCore import Qt from PyQt5.QtGui import QBrush -from PyQt5.QtWidgets import (QFileDialog, QGraphicsScene, QGraphicsView, - QHBoxLayout, QMainWindow, QMdiSubWindow, - QMessageBox, QTabWidget, QWidget, QMenuBar, QHBoxLayout) +from PyQt5.QtWidgets import (QComboBox, QDialog, QFileDialog, QFormLayout, + QGraphicsScene, QGraphicsView, QHBoxLayout, + QLabel, QMainWindow, QMdiSubWindow, QMenu, + QMessageBox, QTabWidget, QWidget) from . import graphics from .sizes import paperSizes, ppiList, sheetDimensionList +from .tabs import customTabWidget class canvas(QWidget): @@ -30,6 +32,9 @@ class canvas(QWidget): self.layout.addWidget(self.view) self.setLayout(self.layout) + self.setContextMenuPolicy(Qt.CustomContextMenu) + self.customContextMenuRequested.connect(self.contextMenu) + def setCanvasSize(self, size): self.canvasSize = size @@ -61,6 +66,36 @@ class canvas(QWidget): def dimensions(self): return self.painter.sceneRect().width(), self.painter.sceneRect().height() + def contextMenu(self, point): + menu = QMenu("Context Menu", self) + menu.addAction("Adjust Canvas", self.adjustCanvasDialog) + menu.exec_(self.mapToGlobal(point)) + + def adjustCanvasDialog(self): + dialogBox = QDialog(self) + dialogBoxLayout = QFormLayout(dialogBox) + sizeComboBox = QComboBox() + sizeComboBox.addItems(sheetDimensionList) + sizeComboBox.setCurrentIndex(4) + sizeComboBox.activated[str].connect(self.setCanvasSize) + sizeLabel = QLabel("Canvas Size") + sizeLabel.setBuddy(sizeComboBox) + sizeComboBox.setCurrentIndex(sheetDimensionList.index(self.canvasSize)) + dialogBoxLayout.setWidget(0, QFormLayout.LabelRole, sizeLabel) + dialogBoxLayout.setWidget(0, QFormLayout.FieldRole, sizeComboBox) + + ppiComboBox = QComboBox() + ppiComboBox.addItems(ppiList) + ppiComboBox.activated[str].connect(self.setCanvasPPI) + ppiLabel = QLabel("Canvas ppi") + ppiLabel.setBuddy(ppiComboBox) + ppiComboBox.setCurrentIndex(ppiList.index(self.ppi)) + dialogBoxLayout.setWidget(1, QFormLayout.LabelRole, ppiLabel) + dialogBoxLayout.setWidget(1, QFormLayout.FieldRole, ppiComboBox) + dialogBox.setLayout(dialogBoxLayout) + + dialogBox.show() + def __getstate__(self) -> dict: return { "_classname_": self.__class__.__name__, @@ -86,22 +121,14 @@ class fileWindow(QMdiSubWindow): self._ppi = ppi self._canvasSize = size - self.widget = QWidget(self) - layout = QHBoxLayout(self.widget) - self.tabber = QTabWidget(self.widget) + self.tabber = customTabWidget(self) self.tabber.setObjectName(title) - self.tabber.setTabsClosable(True) self.tabber.tabCloseRequested.connect(self.closeTab) self.tabber.currentChanged.connect(self.changeTab) - layout.addWidget(self.tabber) + self.tabber.tab.plusClicked.connect(self.newDiagram) - titleMenu = QMenuBar(self) - menuFile = titleMenu.addMenu('File') #File Menu - menuFile.addAction("New", self.newDiagram) - layout.setMenuBar(titleMenu) - self.widget.setLayout(layout) - self.setWidget(self.widget) + self.setWidget(self.tabber) self.setWindowTitle(title) @property @@ -141,11 +168,11 @@ class fileWindow(QMdiSubWindow): def resizeHandler(self, parent = None): parentRect = parent.rect() if parent else self.parent().rect() - self.resize(parentRect().width(), parentRect().height()) - self.setMaximumHeight(parentRect().height()) - self.tabber.setMaximumHeight(parentRect().height()) + self.resize(parentRect.width(), parentRect.height()) + self.setMaximumHeight(parentRect.height()) + self.tabber.setMaximumHeight(parentRect.height()) for i in self.tabList: - i.setMaximumHeight(parentRect().height()) + i.setMaximumHeight(parentRect.height()) @property def tabList(self): @@ -195,4 +222,4 @@ class fileWindow(QMdiSubWindow): if alert == QMessageBox.Save: if not self.saveProject(): return False - return True \ No newline at end of file + return True diff --git a/src/main/python/utils/tabs.py b/src/main/python/utils/tabs.py new file mode 100644 index 0000000..695a7fc --- /dev/null +++ b/src/main/python/utils/tabs.py @@ -0,0 +1,51 @@ +from PyQt5.QtWidgets import QTabBar, QPushButton, QTabWidget +from PyQt5.QtCore import pyqtSignal, QSize + +class tabBarPlus(QTabBar): + plusClicked = pyqtSignal() + def __init__(self): + super().__init__() + + self.plusButton = QPushButton("+", self) + self.plusButton.setParent(self) + self.setTabButton(0, QTabBar.RightSide, self.plusButton) + self.plusButton.setFixedSize(20, 20) + self.plusButton.clicked.connect(self.plusClicked.emit) + # self.movePlusButton() + + def sizeHint(self): + sizeHint = QTabBar.sizeHint(self) + width = sizeHint.width() + height = sizeHint.height() + return QSize(width+25, height) + + def resizeEvent(self, event): + super().resizeEvent(event) + # self.movePlusButton() + + def tabLayoutChange(self): + super().tabLayoutChange() + # self.movePlusButton() + + def movePlusButton(self): + size = sum([self.tabRect(i).width() for i in range(self.count())]) + h = self.geometry().top() + w = self.width() + if size > w: + self.plusButton.move(w-54, h) + else: + self.plusButton.move(size, h) + +class customTabWidget(QTabWidget): + + def __init__(self, parent=None): + super(customTabWidget, self).__init__(parent) + + self.tab = tabBarPlus() + self.setTabBar(self.tab) + + self.setMovable(True) + self.setTabsClosable(True) + + # self.tab.tabMoved.connect(self.moveTab) + # self.tabCloseRequested.connect(self.removeTab) \ No newline at end of file -- cgit From 2d5481919e2030ad66183b0bea8f9702d5f8a2db Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 25 Apr 2020 09:13:05 +0530 Subject: fixed new tab button --- src/main/python/main.py | 16 +++++++------ src/main/python/utils/canvas.py | 7 +++--- src/main/python/utils/tabs.py | 50 +++++++++++++++++------------------------ 3 files changed, 33 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 52a8a33..66748cc 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -8,7 +8,7 @@ from PyQt5.QtWidgets import (QComboBox, QFileDialog, QFormLayout, QGraphicsScene, QGraphicsView, QGridLayout, QHBoxLayout, QLabel, QMainWindow, QMenu, QMenuBar, QPushButton, QTabWidget, QWidget, QMdiArea, QMessageBox) - +# from utils.canvas import canvas, fileWindow from utils.sizes import ppiList, sheetDimensionList @@ -53,8 +53,7 @@ class appWindow(QMainWindow): self.toolbar.setObjectName("Toolbar") self.toolbar.setFixedWidth(200) toolbarLayout = QFormLayout(self.toolbar) - self.toolbar.setLayout(toolbarLayout) - + self.toolbar.setLayout(toolbarLayout) def setCanvasSize(self, size): self._defaultCanvasSize = size @@ -85,8 +84,7 @@ class appWindow(QMainWindow): project = pickle.load(file) self.mdi.addSubWindow(project) project.show() - project.resizeHandler(self.mdi) - + project.resizeHandler(self.mdi) def saveProject(self): for j, i in enumerate(self.mdi.subWindowList()): @@ -112,7 +110,7 @@ class appWindow(QMainWindow): event.ignore() def saveEvent(self): - if self.mdi.subWindowList(): + if len(self.activeFiles): alert = QMessageBox.question(self, self.objectName(), "All unsaved progress will be LOST!", QMessageBox.StandardButtons(QMessageBox.Save|QMessageBox.Ignore|QMessageBox.Cancel), QMessageBox.Save) @@ -123,7 +121,11 @@ class appWindow(QMainWindow): if not self.saveProject(): return False return True - + + @property + def activeFiles(self): + return filter(lambda x: x.tabCount()>=1, self.mdi.subWindowList()) + if __name__ == '__main__': app = ApplicationContext() # 1. Instantiate ApplicationContext test = appWindow() diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 9578b1a..fe5b527 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -73,6 +73,7 @@ class canvas(QWidget): def adjustCanvasDialog(self): dialogBox = QDialog(self) + dialogBox.setWindowTitle(self.objectName()+":Canvas Size") dialogBoxLayout = QFormLayout(dialogBox) sizeComboBox = QComboBox() sizeComboBox.addItems(sheetDimensionList) @@ -94,7 +95,7 @@ class canvas(QWidget): dialogBoxLayout.setWidget(1, QFormLayout.FieldRole, ppiComboBox) dialogBox.setLayout(dialogBoxLayout) - dialogBox.show() + dialogBox.exec_() def __getstate__(self) -> dict: return { @@ -126,7 +127,7 @@ class fileWindow(QMdiSubWindow): self.tabber.setObjectName(title) self.tabber.tabCloseRequested.connect(self.closeTab) self.tabber.currentChanged.connect(self.changeTab) - self.tabber.tab.plusClicked.connect(self.newDiagram) + self.tabber.plusClicked.connect(self.newDiagram) self.setWidget(self.tabber) self.setWindowTitle(title) @@ -208,7 +209,7 @@ class fileWindow(QMdiSubWindow): return False def closeEvent(self, event): - if self.saveEvent(): + if self.tabCount or self.saveEvent(): event.accept() else: event.ignore() diff --git a/src/main/python/utils/tabs.py b/src/main/python/utils/tabs.py index 695a7fc..634a4ff 100644 --- a/src/main/python/utils/tabs.py +++ b/src/main/python/utils/tabs.py @@ -2,50 +2,40 @@ from PyQt5.QtWidgets import QTabBar, QPushButton, QTabWidget from PyQt5.QtCore import pyqtSignal, QSize class tabBarPlus(QTabBar): - plusClicked = pyqtSignal() - def __init__(self): - super().__init__() - - self.plusButton = QPushButton("+", self) - self.plusButton.setParent(self) - self.setTabButton(0, QTabBar.RightSide, self.plusButton) - self.plusButton.setFixedSize(20, 20) - self.plusButton.clicked.connect(self.plusClicked.emit) - # self.movePlusButton() - - def sizeHint(self): - sizeHint = QTabBar.sizeHint(self) - width = sizeHint.width() - height = sizeHint.height() - return QSize(width+25, height) - + layoutChanged = pyqtSignal() def resizeEvent(self, event): super().resizeEvent(event) - # self.movePlusButton() + self.layoutChanged.emit() def tabLayoutChange(self): super().tabLayoutChange() - # self.movePlusButton() + self.layoutChanged.emit() - def movePlusButton(self): - size = sum([self.tabRect(i).width() for i in range(self.count())]) - h = self.geometry().top() - w = self.width() - if size > w: - self.plusButton.move(w-54, h) - else: - self.plusButton.move(size, h) class customTabWidget(QTabWidget): - + plusClicked = pyqtSignal() def __init__(self, parent=None): super(customTabWidget, self).__init__(parent) self.tab = tabBarPlus() self.setTabBar(self.tab) - + + self.plusButton = QPushButton('+', self) + self.plusButton.setFixedSize(20, 20) + self.plusButton.clicked.connect(self.plusClicked.emit) self.setMovable(True) self.setTabsClosable(True) + self.tab.layoutChanged.connect(self.movePlusButton) # self.tab.tabMoved.connect(self.moveTab) - # self.tabCloseRequested.connect(self.removeTab) \ No newline at end of file + # self.tabCloseRequested.connect(self.removeTab) + + def movePlusButton(self): + size = sum([self.tab.tabRect(i).width() for i in range(self.tab.count())]) + h = max(self.tab.geometry().bottom() - 20, 0) + w = self.tab.width() + print(size, w, h) + if size > w: + self.plusButton.move(w-self.plusButton.width(), h) + else: + self.plusButton.move(size, h) \ No newline at end of file -- cgit From 5860a05ba2f804815c704f0a14ea74fe11b20771 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 25 Apr 2020 09:20:40 +0530 Subject: streamline new tab button --- src/main/python/utils/tabs.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/tabs.py b/src/main/python/utils/tabs.py index 634a4ff..085c37f 100644 --- a/src/main/python/utils/tabs.py +++ b/src/main/python/utils/tabs.py @@ -21,21 +21,19 @@ class customTabWidget(QTabWidget): self.setTabBar(self.tab) self.plusButton = QPushButton('+', self) - self.plusButton.setFixedSize(20, 20) + self.plusButton.setFixedSize(35, 25) self.plusButton.clicked.connect(self.plusClicked.emit) self.setMovable(True) self.setTabsClosable(True) self.tab.layoutChanged.connect(self.movePlusButton) - # self.tab.tabMoved.connect(self.moveTab) - # self.tabCloseRequested.connect(self.removeTab) def movePlusButton(self): size = sum([self.tab.tabRect(i).width() for i in range(self.tab.count())]) - h = max(self.tab.geometry().bottom() - 20, 0) + h = max(self.tab.geometry().bottom() - 24, 0) w = self.tab.width() print(size, w, h) if size > w: self.plusButton.move(w-self.plusButton.width(), h) else: - self.plusButton.move(size, h) \ No newline at end of file + self.plusButton.move(size-3, h) \ No newline at end of file -- cgit From 73e4e7fc107b2df628a2195a93f2966561021718 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 25 Apr 2020 09:26:37 +0530 Subject: fixed edge case for close event --- src/main/python/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 66748cc..0e29d88 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -124,7 +124,7 @@ class appWindow(QMainWindow): @property def activeFiles(self): - return filter(lambda x: x.tabCount()>=1, self.mdi.subWindowList()) + return [i for i in self.mdi.subWindowList() if i.tabCount] if __name__ == '__main__': app = ApplicationContext() # 1. Instantiate ApplicationContext -- cgit From c40fbc6502d7375ef8b666c32baf8266a132867e Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 25 Apr 2020 09:27:07 +0530 Subject: remove debugging statment --- src/main/python/utils/tabs.py | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/main/python/utils/tabs.py b/src/main/python/utils/tabs.py index 085c37f..cc0c195 100644 --- a/src/main/python/utils/tabs.py +++ b/src/main/python/utils/tabs.py @@ -32,7 +32,6 @@ class customTabWidget(QTabWidget): size = sum([self.tab.tabRect(i).width() for i in range(self.tab.count())]) h = max(self.tab.geometry().bottom() - 24, 0) w = self.tab.width() - print(size, w, h) if size > w: self.plusButton.move(w-self.plusButton.width(), h) else: -- cgit From c05d821f561fc417349a0bf95e4ca95668ff1065 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 25 Apr 2020 09:30:07 +0530 Subject: memory is freed when file is closed --- src/main/python/utils/canvas.py | 1 + src/main/python/utils/tabs.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index fe5b527..db72f05 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -211,6 +211,7 @@ class fileWindow(QMdiSubWindow): def closeEvent(self, event): if self.tabCount or self.saveEvent(): event.accept() + self.deleteLater() else: event.ignore() diff --git a/src/main/python/utils/tabs.py b/src/main/python/utils/tabs.py index cc0c195..3dfb641 100644 --- a/src/main/python/utils/tabs.py +++ b/src/main/python/utils/tabs.py @@ -30,7 +30,7 @@ class customTabWidget(QTabWidget): def movePlusButton(self): size = sum([self.tab.tabRect(i).width() for i in range(self.tab.count())]) - h = max(self.tab.geometry().bottom() - 24, 0) + h = max(self.tab.geometry().bottom() - 25, 0) w = self.tab.width() if size > w: self.plusButton.move(w-self.plusButton.width(), h) -- cgit From fd3c77a435982b82de5fa55f18a814c9644aec30 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 25 Apr 2020 09:34:09 +0530 Subject: missed file close conditions --- src/main/python/utils/canvas.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index db72f05..270cf17 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -209,7 +209,7 @@ class fileWindow(QMdiSubWindow): return False def closeEvent(self, event): - if self.tabCount or self.saveEvent(): + if self.tabCount==0 or self.saveEvent(): event.accept() self.deleteLater() else: -- cgit From 0477ce548a303c20c33eb7abc8fe6166f18c3359 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 25 Apr 2020 12:19:48 +0530 Subject: cleanup and reorganize --- src/main/python/main.py | 39 ++++++----------------------- src/main/python/utils/canvas.py | 48 ++++-------------------------------- src/main/python/utils/dialogs.py | 53 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 74 deletions(-) create mode 100644 src/main/python/utils/dialogs.py (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 0e29d88..953c6c8 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -8,16 +8,15 @@ from PyQt5.QtWidgets import (QComboBox, QFileDialog, QFormLayout, QGraphicsScene, QGraphicsView, QGridLayout, QHBoxLayout, QLabel, QMainWindow, QMenu, QMenuBar, QPushButton, QTabWidget, QWidget, QMdiArea, QMessageBox) -# + from utils.canvas import canvas, fileWindow from utils.sizes import ppiList, sheetDimensionList +from utils import dialogs class appWindow(QMainWindow): def __init__(self, parent=None): super(appWindow, self).__init__(parent) - self._defaultPPI = '72' - self._defaultCanvasSize = "A4" titleMenu = self.menuBar() self.mainWidget = QWidget(self) @@ -53,22 +52,10 @@ class appWindow(QMainWindow): self.toolbar.setObjectName("Toolbar") self.toolbar.setFixedWidth(200) toolbarLayout = QFormLayout(self.toolbar) - self.toolbar.setLayout(toolbarLayout) - - def setCanvasSize(self, size): - self._defaultCanvasSize = size - activeCanvas = self.mdi.currentSubWindow() - if activeCanvas: - activeCanvas.canvasSize = size - - def setCanvasPPI(self, ppi): - self._defaultPPI = ppi - activeCanvas = self.mdi.currentSubWindow() - if activeCanvas: - activeCanvas.ppi = ppi + self.toolbar.setLayout(toolbarLayout) def newProject(self): - project = fileWindow(self.mdi, size = self._defaultCanvasSize, ppi = self._defaultPPI) + project = fileWindow(self.mdi) project.setObjectName("New Project") self.mdi.addSubWindow(project) if not project.tabList: @@ -91,6 +78,9 @@ class appWindow(QMainWindow): if i.tabCount: name = QFileDialog.getSaveFileName(self, 'Save File', f'New Diagram {j}', 'Process Flow Diagram (*.pfd)') i.saveProject(name) + else: + return False + return True def saveImage(self): pass @@ -104,23 +94,10 @@ class appWindow(QMainWindow): super(appWindow, self).resizeEvent(event) def closeEvent(self, event): - if self.saveEvent(): + if len(self.activeFiles) and dialogs.saveEvent(self): event.accept() else: event.ignore() - - def saveEvent(self): - if len(self.activeFiles): - alert = QMessageBox.question(self, self.objectName(), "All unsaved progress will be LOST!", - QMessageBox.StandardButtons(QMessageBox.Save|QMessageBox.Ignore|QMessageBox.Cancel), - QMessageBox.Save) - if alert == QMessageBox.Cancel: - return False - else: - if alert == QMessageBox.Save: - if not self.saveProject(): - return False - return True @property def activeFiles(self): diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 270cf17..330d3be 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -7,11 +7,10 @@ from PyQt5.QtWidgets import (QComboBox, QDialog, QFileDialog, QFormLayout, QLabel, QMainWindow, QMdiSubWindow, QMenu, QMessageBox, QTabWidget, QWidget) -from . import graphics +from . import graphics, dialogs from .sizes import paperSizes, ppiList, sheetDimensionList from .tabs import customTabWidget - class canvas(QWidget): def __init__(self, parent=None, size= 'A4', ppi= '72'): super(canvas, self).__init__(parent) @@ -72,30 +71,7 @@ class canvas(QWidget): menu.exec_(self.mapToGlobal(point)) def adjustCanvasDialog(self): - dialogBox = QDialog(self) - dialogBox.setWindowTitle(self.objectName()+":Canvas Size") - dialogBoxLayout = QFormLayout(dialogBox) - sizeComboBox = QComboBox() - sizeComboBox.addItems(sheetDimensionList) - sizeComboBox.setCurrentIndex(4) - sizeComboBox.activated[str].connect(self.setCanvasSize) - sizeLabel = QLabel("Canvas Size") - sizeLabel.setBuddy(sizeComboBox) - sizeComboBox.setCurrentIndex(sheetDimensionList.index(self.canvasSize)) - dialogBoxLayout.setWidget(0, QFormLayout.LabelRole, sizeLabel) - dialogBoxLayout.setWidget(0, QFormLayout.FieldRole, sizeComboBox) - - ppiComboBox = QComboBox() - ppiComboBox.addItems(ppiList) - ppiComboBox.activated[str].connect(self.setCanvasPPI) - ppiLabel = QLabel("Canvas ppi") - ppiLabel.setBuddy(ppiComboBox) - ppiComboBox.setCurrentIndex(ppiList.index(self.ppi)) - dialogBoxLayout.setWidget(1, QFormLayout.LabelRole, ppiLabel) - dialogBoxLayout.setWidget(1, QFormLayout.FieldRole, ppiComboBox) - dialogBox.setLayout(dialogBoxLayout) - - dialogBox.exec_() + self.canvasSize, self.ppi = dialogs.paperDims(self, self._canvasSize, self._ppi, self.objectName).exec_() def __getstate__(self) -> dict: return { @@ -120,9 +96,6 @@ class fileWindow(QMdiSubWindow): def __init__(self, parent = None, title = 'New Project', size = 'A4', ppi = '72'): super(fileWindow, self).__init__(parent) - self._ppi = ppi - self._canvasSize = size - self.tabber = customTabWidget(self) self.tabber.setObjectName(title) self.tabber.tabCloseRequested.connect(self.closeTab) @@ -158,12 +131,12 @@ class fileWindow(QMdiSubWindow): pass def closeTab(self, currentIndex): - if self.saveEvent(): + if dialogs.saveEvent(self): self.tabber.widget(currentIndex).deleteLater() self.tabber.removeTab(currentIndex) def newDiagram(self): - diagram = canvas(self.tabber, size = self._canvasSize, ppi = self._ppi) + diagram = canvas(self.tabber) diagram.setObjectName("New") self.tabber.addTab(diagram, "New") @@ -209,19 +182,8 @@ class fileWindow(QMdiSubWindow): return False def closeEvent(self, event): - if self.tabCount==0 or self.saveEvent(): + if self.tabCount==0 or dialogs.saveEvent(self): event.accept() self.deleteLater() else: event.ignore() - - def saveEvent(self): - alert = QMessageBox.question(self, self.objectName(), "All unsaved progress will be LOST!", - QMessageBox.StandardButtons(QMessageBox.Save|QMessageBox.Ignore|QMessageBox.Cancel), QMessageBox.Save) - if alert == QMessageBox.Cancel: - return False - else: - if alert == QMessageBox.Save: - if not self.saveProject(): - return False - return True diff --git a/src/main/python/utils/dialogs.py b/src/main/python/utils/dialogs.py new file mode 100644 index 0000000..d2b872c --- /dev/null +++ b/src/main/python/utils/dialogs.py @@ -0,0 +1,53 @@ +from PyQt5.QtWidgets import QDialog, QPushButton, QFormLayout, QComboBox, QLabel, QMessageBox +from .sizes import sheetDimensionList, ppiList + +class paperDims(QDialog): + def __init__(self, parent=None, size='A4', ppi='72', name='Canvas Size'): + super(paperDims, self).__init__(parent) + + self._canvasSize = size + self._ppi = ppi + + self.setWindowTitle(name+":Canvas Size") + dialogBoxLayout = QFormLayout(self) + sizeComboBox = QComboBox() + sizeComboBox.addItems(sheetDimensionList) + sizeComboBox.setCurrentIndex(4) + sizeComboBox.activated[str].connect(self.setCanvasSize) + sizeLabel = QLabel("Canvas Size") + sizeLabel.setBuddy(sizeComboBox) + sizeComboBox.setCurrentIndex(sheetDimensionList.index(self._canvasSize)) + dialogBoxLayout.setWidget(0, QFormLayout.LabelRole, sizeLabel) + dialogBoxLayout.setWidget(0, QFormLayout.FieldRole, sizeComboBox) + + ppiComboBox = QComboBox() + ppiComboBox.addItems(ppiList) + ppiComboBox.activated[str].connect(self.setCanvasPPI) + ppiLabel = QLabel("Canvas ppi") + ppiLabel.setBuddy(ppiComboBox) + ppiComboBox.setCurrentIndex(ppiList.index(self._ppi)) + dialogBoxLayout.setWidget(1, QFormLayout.LabelRole, ppiLabel) + dialogBoxLayout.setWidget(1, QFormLayout.FieldRole, ppiComboBox) + self.setLayout(dialogBoxLayout) + self.resize(400,300) + + def setCanvasSize(self, size): + self._canvasSize = size + + def setCanvasPPI(self, ppi): + self._ppi = ppi + + def exec_(self): + super(paperDims, self).exec_() + return self._canvasSize, self._ppi + +def saveEvent(parent = None): + alert = QMessageBox.question(parent, parent.objectName(), "All unsaved progress will be LOST!", + QMessageBox.StandardButtons(QMessageBox.Save|QMessageBox.Ignore|QMessageBox.Cancel), QMessageBox.Save) + if alert == QMessageBox.Cancel: + return False + else: + if alert == QMessageBox.Save: + if not parent.saveProject(): + return False + return True \ No newline at end of file -- cgit From e3cdc7d698a3f400f600e13fa9e647a1d909aff2 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sun, 26 Apr 2020 22:05:13 +0530 Subject: comments and minor cleanup --- src/main/python/main.py | 36 +++++++++---- src/main/python/utils/canvas.py | 114 ++++++++++++++++++++++----------------- src/main/python/utils/dialogs.py | 32 +++++++---- src/main/python/utils/tabs.py | 26 ++++++--- 4 files changed, 133 insertions(+), 75 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 953c6c8..5afb350 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -15,39 +15,46 @@ from utils import dialogs class appWindow(QMainWindow): + """ + Application entry point, subclasses QMainWindow and implements the main widget, + sets necessary window behaviour etc. + """ def __init__(self, parent=None): super(appWindow, self).__init__(parent) + self.mainWidget = QWidget(self) #create new widget - titleMenu = self.menuBar() - self.mainWidget = QWidget(self) + #create the menu bar + titleMenu = self.menuBar() #fetch reference to current menu bar self.mainWidget.setObjectName("Main Widget") self.menuFile = titleMenu.addMenu('File') #File Menu self.menuFile.addAction("New", self.newProject) self.menuFile.addAction("Open", self.openProject) self.menuFile.addAction("Save", self.saveProject) + self.menuGenerate = titleMenu.addMenu('Generate') #Generate menu self.menuGenerate.addAction("Image", self.saveImage) self.menuGenerate.addAction("Report", self.generateReport) - # mainLayout = QGridLayout(self.mainWidget) + # create new layout for the main widget mainLayout = QHBoxLayout(self.mainWidget) mainLayout.setObjectName("Main Layout") - #ImpsaveProject - self.mdi = QMdiArea(self) - # add close action to tabs + self.mdi = QMdiArea(self) #create area for files to be displayed + #create toolbar and add the toolbar plus mdi to layout self.createToolbar() mainLayout.addWidget(self.toolbar) mainLayout.addWidget(self.mdi) + #declare main window layout self.mainWidget.setLayout(mainLayout) self.setCentralWidget(self.mainWidget) - self.resize(1280, 720) - self.setWindowState(Qt.WindowMaximized) + self.resize(1280, 720) #set collapse dim + self.setWindowState(Qt.WindowMaximized) #launch maximized def createToolbar(self): + #place holder for toolbar with fixed width, layout may change self.toolbar = QWidget(self.mainWidget) self.toolbar.setObjectName("Toolbar") self.toolbar.setFixedWidth(200) @@ -55,15 +62,17 @@ class appWindow(QMainWindow): self.toolbar.setLayout(toolbarLayout) def newProject(self): + #call to create a new file inside mdi area project = fileWindow(self.mdi) project.setObjectName("New Project") self.mdi.addSubWindow(project) - if not project.tabList: - project.newDiagram() + if not project.tabList: # important when unpickling a file instead + project.newDiagram() #create a new tab in the new file project.show() project.resizeHandler(self.mdi) def openProject(self): + #show the open file dialog to open a saved file, then unpickle it. name = QFileDialog.getOpenFileNames(self, 'Open File(s)', '', 'Process Flow Diagram (*pfd)') if name: for files in name[0]: @@ -74,7 +83,8 @@ class appWindow(QMainWindow): project.resizeHandler(self.mdi) def saveProject(self): - for j, i in enumerate(self.mdi.subWindowList()): + #pickle all files in mdi area + for j, i in enumerate(self.mdi.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)') i.saveProject(name) @@ -83,17 +93,21 @@ class appWindow(QMainWindow): return True def saveImage(self): + #place holder for future implementaion pass def generateReport(self): + #place holder for future implementaion pass def resizeEvent(self, event): + #overload resize to also handle resize on file windows inside if self.mdi.activeSubWindow(): self.mdi.activeSubWindow().resizeHandler(self.mdi) super(appWindow, self).resizeEvent(event) def closeEvent(self, event): + #save alert on window close if len(self.activeFiles) and dialogs.saveEvent(self): event.accept() else: diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 330d3be..dac1d98 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -12,32 +12,48 @@ from .sizes import paperSizes, ppiList, sheetDimensionList from .tabs import customTabWidget class canvas(QWidget): + """ + Defines the work area for a single sheet. Contains a QGraphicScene along with necessary properties + for context menu and dialogs. + """ + def __init__(self, parent=None, size= 'A4', ppi= '72'): super(canvas, self).__init__(parent) + #Store values for the canvas dimensions for ease of access, these are here just to be + # manipulated by the setters and getters self._ppi = ppi self._canvasSize = size + #Create area for the graphic items to be placed, this is just here right now for the future + # when we will draw items on this, this might be changed if QGraphicScene is subclassed. self.painter = QGraphicsScene() self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) - self.painter.setBackgroundBrush(QBrush(Qt.white)) + self.painter.setBackgroundBrush(QBrush(Qt.white)) #set white background - self.view = QGraphicsView(self.painter) - self.view.setMinimumSize(595, 842) - self.view.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) + self.view = QGraphicsView(self.painter) #create a viewport for the canvas board + self.view.setMinimumSize(595, 842) #experimentation for the viewport overflow + self.view.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) # use the dimensions set previously - self.layout = QHBoxLayout(self) + self.layout = QHBoxLayout(self) #create the layout of the canvas, the canvas could just subclass QGView instead self.layout.addWidget(self.view) self.setLayout(self.layout) + #This is done so that a right click menu is shown on right click self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.contextMenu) def setCanvasSize(self, size): + """ + extended setter for dialog box + """ self.canvasSize = size - def setCanvasPPI(self, ppi): + def setCanvasPPI(self, ppi): + """ + extended setter for dialog box + """ self.ppi = ppi @property @@ -63,16 +79,21 @@ class canvas(QWidget): @property def dimensions(self): + #returns the dimension of the current scene return self.painter.sceneRect().width(), self.painter.sceneRect().height() def contextMenu(self, point): + #function to display the right click menu at point of right click menu = QMenu("Context Menu", self) menu.addAction("Adjust Canvas", self.adjustCanvasDialog) menu.exec_(self.mapToGlobal(point)) def adjustCanvasDialog(self): + #helper function to the context menu dialog box self.canvasSize, self.ppi = dialogs.paperDims(self, self._canvasSize, self._ppi, self.objectName).exec_() + #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. def __getstate__(self) -> dict: return { "_classname_": self.__class__.__name__, @@ -93,54 +114,43 @@ class canvas(QWidget): self.painter.addItem(graphic) class fileWindow(QMdiSubWindow): + """ + This defines a single file, inside the application, consisting of multiple tabs that contain + canvases. Pre-Defined so that a file can be instantly created without defining the structure again. + """ def __init__(self, parent = None, title = 'New Project', size = 'A4', ppi = '72'): super(fileWindow, self).__init__(parent) + #Uses a custom QTabWidget that houses a custom new Tab Button, used to house the seperate + # diagrams inside a file self.tabber = customTabWidget(self) - self.tabber.setObjectName(title) - self.tabber.tabCloseRequested.connect(self.closeTab) - self.tabber.currentChanged.connect(self.changeTab) - self.tabber.plusClicked.connect(self.newDiagram) + self.tabber.setObjectName(title) #store title as object name for pickling + self.tabber.tabCloseRequested.connect(self.closeTab) # Show save alert on tab close + self.tabber.currentChanged.connect(self.changeTab) # placeholder just to detect tab change + self.tabber.plusClicked.connect(self.newDiagram) #connect the new tab button to add a new tab + #assign layout to widget self.setWidget(self.tabber) - self.setWindowTitle(title) - - @property - def canvasSize(self): - return self._canvasSize - @property - def ppi(self): - return self._ppi - - @canvasSize.setter - def canvasSize(self, size): - self._canvasSize = sheetDimensionList.index(size) - if self.tabCount: - activeTab = self.tabber.currentWidget() - activeTab.canvasSize = size - - @ppi.setter - def ppi(self, ppi): - self._ppi = ppiList.index(ppi) - if self.tabCount: - activeTab = self.tabber.currentWidget() - activeTab.ppi = ppi - + self.setWindowTitle(title) def changeTab(self, currentIndex): + #placeholder function to detect tab change pass def closeTab(self, currentIndex): + #show save alert on tab close if dialogs.saveEvent(self): self.tabber.widget(currentIndex).deleteLater() self.tabber.removeTab(currentIndex) def newDiagram(self): + # 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") self.tabber.addTab(diagram, "New") def resizeHandler(self, parent = None): + # experimental resize Handler to handle resize on parent resize. parentRect = parent.rect() if parent else self.parent().rect() self.resize(parentRect.width(), parentRect.height()) self.setMaximumHeight(parentRect.height()) @@ -150,12 +160,34 @@ class fileWindow(QMdiSubWindow): @property def tabList(self): + #returns a list of tabs in the given window return [self.tabber.widget(i) for i in range(self.tabCount)] @property def tabCount(self): + #returns the number of tabs in the given window only return self.tabber.count() + 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: + with open(name[0],'wb') as file: + pickle.dump(self, file) + return True + else: + return False + + def closeEvent(self, event): + # handle save alert on file close, check if current file has no tabs aswell. + if self.tabCount==0 or dialogs.saveEvent(self): + event.accept() + self.deleteLater() + 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. def __getstate__(self) -> dict: return { "_classname_": self.__class__.__name__, @@ -172,18 +204,4 @@ class fileWindow(QMdiSubWindow): diagram.__setstate__(i) self.tabber.addTab(diagram, i['ObjectName']) - def saveProject(self, name = None): - name = QFileDialog.getSaveFileName(self, 'Save File', f'New Diagram', 'Process Flow Diagram (*.pfd)') if not name else name - if name: - with open(name[0],'wb') as file: - pickle.dump(self, file) - return True - else: - return False - - def closeEvent(self, event): - if self.tabCount==0 or dialogs.saveEvent(self): - event.accept() - self.deleteLater() - else: - event.ignore() + \ No newline at end of file diff --git a/src/main/python/utils/dialogs.py b/src/main/python/utils/dialogs.py index d2b872c..38d68d9 100644 --- a/src/main/python/utils/dialogs.py +++ b/src/main/python/utils/dialogs.py @@ -2,52 +2,66 @@ from PyQt5.QtWidgets import QDialog, QPushButton, QFormLayout, QComboBox, QLabel from .sizes import sheetDimensionList, ppiList class paperDims(QDialog): + """ + Utility dialog box to adjust the current canvas's dimensions, might return just dimensions later + so that sizes do not need to be imported in every other module. + """ def __init__(self, parent=None, size='A4', ppi='72', name='Canvas Size'): super(paperDims, self).__init__(parent) + #store initial values to show currently set value, also updated when changed. these are returned at EOL self._canvasSize = size self._ppi = ppi - self.setWindowTitle(name+":Canvas Size") + self.setWindowTitle(name+":Canvas Size") #Set Window Title + #init layout dialogBoxLayout = QFormLayout(self) - sizeComboBox = QComboBox() + + sizeComboBox = QComboBox() #combo box for paper sizes sizeComboBox.addItems(sheetDimensionList) sizeComboBox.setCurrentIndex(4) sizeComboBox.activated[str].connect(self.setCanvasSize) sizeLabel = QLabel("Canvas Size") - sizeLabel.setBuddy(sizeComboBox) - sizeComboBox.setCurrentIndex(sheetDimensionList.index(self._canvasSize)) + sizeLabel.setBuddy(sizeComboBox) # label for the above combo box + sizeComboBox.setCurrentIndex(sheetDimensionList.index(self._canvasSize)) #set index to current value of canvas dialogBoxLayout.setWidget(0, QFormLayout.LabelRole, sizeLabel) dialogBoxLayout.setWidget(0, QFormLayout.FieldRole, sizeComboBox) - ppiComboBox = QComboBox() + ppiComboBox = QComboBox() #combo box for ppis ppiComboBox.addItems(ppiList) ppiComboBox.activated[str].connect(self.setCanvasPPI) ppiLabel = QLabel("Canvas ppi") - ppiLabel.setBuddy(ppiComboBox) - ppiComboBox.setCurrentIndex(ppiList.index(self._ppi)) + ppiLabel.setBuddy(ppiComboBox) # label for the above combo box + ppiComboBox.setCurrentIndex(ppiList.index(self._ppi)) #set index to current value of canvas dialogBoxLayout.setWidget(1, QFormLayout.LabelRole, ppiLabel) dialogBoxLayout.setWidget(1, QFormLayout.FieldRole, ppiComboBox) self.setLayout(dialogBoxLayout) - self.resize(400,300) + self.resize(400,300) #resize to a certain size + + #todo add ok or cancel buttons def setCanvasSize(self, size): + #for standard combo box behaviour self._canvasSize = size def setCanvasPPI(self, ppi): + #for standard combo box behaviour self._ppi = ppi def exec_(self): + #overload exec_ to add return values and delete itself(currently being tested) super(paperDims, self).exec_() + self.deleteLater() return self._canvasSize, self._ppi def saveEvent(parent = None): + #utility function to generate a Qt alert window requesting the user to save the file, returns user intention on window close alert = QMessageBox.question(parent, parent.objectName(), "All unsaved progress will be LOST!", QMessageBox.StandardButtons(QMessageBox.Save|QMessageBox.Ignore|QMessageBox.Cancel), QMessageBox.Save) if alert == QMessageBox.Cancel: return False else: if alert == QMessageBox.Save: - if not parent.saveProject(): + if not parent.saveProject(): #the parent's saveProject method is called which returns false if saving was cancelled by the user return False return True \ No newline at end of file diff --git a/src/main/python/utils/tabs.py b/src/main/python/utils/tabs.py index 3dfb641..7d8bb1d 100644 --- a/src/main/python/utils/tabs.py +++ b/src/main/python/utils/tabs.py @@ -2,6 +2,9 @@ from PyQt5.QtWidgets import QTabBar, QPushButton, QTabWidget from PyQt5.QtCore import pyqtSignal, QSize class tabBarPlus(QTabBar): + """ + Just implemented to overload resize and layout change to emit a signal + """ layoutChanged = pyqtSignal() def resizeEvent(self, event): super().resizeEvent(event) @@ -13,26 +16,35 @@ class tabBarPlus(QTabBar): class customTabWidget(QTabWidget): + """ + QTabWidget with a new tab button, also catches layoutChange signal by + the tabBarPlus to dynamically move the button to the correct location + """ plusClicked = pyqtSignal() def __init__(self, parent=None): super(customTabWidget, self).__init__(parent) self.tab = tabBarPlus() - self.setTabBar(self.tab) + self.setTabBar(self.tab) #set tabBar to our custom tabBarPlus - self.plusButton = QPushButton('+', self) - self.plusButton.setFixedSize(35, 25) - self.plusButton.clicked.connect(self.plusClicked.emit) + self.plusButton = QPushButton('+', self) #create the new tab button + #and parent it to the widget to add it at 0, 0 + self.plusButton.setFixedSize(35, 25) #set dimensions + self.plusButton.clicked.connect(self.plusClicked.emit) #emit signal on click + #set flags self.setMovable(True) self.setTabsClosable(True) - self.tab.layoutChanged.connect(self.movePlusButton) + self.tab.layoutChanged.connect(self.movePlusButton) #connect layout change + # to dynamically move the button. def movePlusButton(self): + #move the new tab button to correct location size = sum([self.tab.tabRect(i).width() for i in range(self.tab.count())]) - h = max(self.tab.geometry().bottom() - 25, 0) + # calculate width of all tabs + h = max(self.tab.geometry().bottom() - 25, 0) #align with bottom of tabbar w = self.tab.width() - if size > w: + if size > w: #if all the tabs do not overflow the tab bar, add at the end self.plusButton.move(w-self.plusButton.width(), h) else: self.plusButton.move(size-3, h) \ No newline at end of file -- cgit From 937c906c45123ad611b08dd2bfc40c8cca861435 Mon Sep 17 00:00:00 2001 From: Blaine Date: Mon, 27 Apr 2020 13:08:30 +0530 Subject: Fixed a few bugs --- src/main/python/main.py | 6 +++--- src/main/python/utils/dialogs.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 5afb350..eb1805a 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -108,10 +108,10 @@ class appWindow(QMainWindow): def closeEvent(self, event): #save alert on window close - if len(self.activeFiles) and dialogs.saveEvent(self): - event.accept() + if len(self.activeFiles) and not dialogs.saveEvent(self): + event.ignore() else: - event.ignore() + event.accept() @property def activeFiles(self): diff --git a/src/main/python/utils/dialogs.py b/src/main/python/utils/dialogs.py index 38d68d9..8d5045b 100644 --- a/src/main/python/utils/dialogs.py +++ b/src/main/python/utils/dialogs.py @@ -13,7 +13,7 @@ class paperDims(QDialog): self._canvasSize = size self._ppi = ppi - self.setWindowTitle(name+":Canvas Size") #Set Window Title + self.setWindowTitle(name+" :Canvas Size") #Set Window Title #init layout dialogBoxLayout = QFormLayout(self) @@ -51,7 +51,7 @@ class paperDims(QDialog): def exec_(self): #overload exec_ to add return values and delete itself(currently being tested) super(paperDims, self).exec_() - self.deleteLater() + # self.deleteLater() return self._canvasSize, self._ppi def saveEvent(parent = None): -- cgit From 54a2775fac3c3cd88f476030047682e904a834ae Mon Sep 17 00:00:00 2001 From: Blaine Date: Mon, 27 Apr 2020 22:42:52 +0530 Subject: implemented fixed canvas size --- src/main/python/utils/canvas.py | 46 +++++++++++++++++++++++++--------------- src/main/python/utils/dialogs.py | 2 +- 2 files changed, 30 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index dac1d98..696c736 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -1,11 +1,11 @@ import pickle from PyQt5.QtCore import Qt -from PyQt5.QtGui import QBrush -from PyQt5.QtWidgets import (QComboBox, QDialog, QFileDialog, QFormLayout, +from PyQt5.QtGui import QBrush, QPalette +from PyQt5.QtWidgets import (QFileDialog, QFormLayout, QGraphicsScene, QGraphicsView, QHBoxLayout, - QLabel, QMainWindow, QMdiSubWindow, QMenu, - QMessageBox, QTabWidget, QWidget) + QMdiSubWindow, QMenu, + QTabWidget, QWidget, QSpacerItem) from . import graphics, dialogs from .sizes import paperSizes, ppiList, sheetDimensionList @@ -24,21 +24,22 @@ class canvas(QWidget): # manipulated by the setters and getters self._ppi = ppi self._canvasSize = size - + # self.setFixedSize(parent.size()) #Create area for the graphic items to be placed, this is just here right now for the future # when we will draw items on this, this might be changed if QGraphicScene is subclassed. - self.painter = QGraphicsScene() - self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) - + self.painter = QGraphicsScene() self.painter.setBackgroundBrush(QBrush(Qt.white)) #set white background self.view = QGraphicsView(self.painter) #create a viewport for the canvas board - self.view.setMinimumSize(595, 842) #experimentation for the viewport overflow - self.view.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) # use the dimensions set previously self.layout = QHBoxLayout(self) #create the layout of the canvas, the canvas could just subclass QGView instead - self.layout.addWidget(self.view) - self.setLayout(self.layout) + self.layout.addWidget(self.view, stretch = 1, alignment= Qt.AlignLeft) + self.spacer = QSpacerItem(1, self.height()) #Horizonatal spacer to force view to not expand to fill widget + self.layout.addSpacerItem(self.spacer) + + #set layout and background color + self.setPalette(self.palette) + self.setLayout(self.layout) #This is done so that a right click menu is shown on right click self.setContextMenuPolicy(Qt.CustomContextMenu) @@ -67,21 +68,30 @@ class canvas(QWidget): def canvasSize(self, size): self._canvasSize = size if self.painter: - self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) - self.view.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) + self.resizeView(*paperSizes[self.canvasSize][self.ppi]) @ppi.setter def ppi(self, ppi): self._ppi = ppi if self.painter: - self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) - self.view.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) + self.resizeView(*paperSizes[self.canvasSize][self.ppi]) @property def dimensions(self): #returns the dimension of the current scene return self.painter.sceneRect().width(), self.painter.sceneRect().height() + def resizeView(self, w=None, h=None): + #resize canvas to appropriate size. + if w is None and h is None: + w, h = paperSizes[self.canvasSize][self.ppi] + self.painter.setSceneRect(0, 0, w, h) + self.view.setSceneRect(0, 0, w, h) + w = min(self.width() - 5, w) + h = self.height() - 5 + self.view.setFixedWidth(w) + self.view.setFixedHeight(h) + def contextMenu(self, point): #function to display the right click menu at point of right click menu = QMenu("Context Menu", self) @@ -90,7 +100,7 @@ class canvas(QWidget): def adjustCanvasDialog(self): #helper function to the context menu dialog box - self.canvasSize, self.ppi = dialogs.paperDims(self, self._canvasSize, self._ppi, self.objectName).exec_() + self.canvasSize, self.ppi = dialogs.paperDims(self, self._canvasSize, self._ppi, self.objectName()).exec_() #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. @@ -148,6 +158,7 @@ class fileWindow(QMdiSubWindow): diagram = canvas(self.tabber) diagram.setObjectName("New") self.tabber.addTab(diagram, "New") + diagram.resizeView() def resizeHandler(self, parent = None): # experimental resize Handler to handle resize on parent resize. @@ -157,6 +168,7 @@ class fileWindow(QMdiSubWindow): self.tabber.setMaximumHeight(parentRect.height()) for i in self.tabList: i.setMaximumHeight(parentRect.height()) + self.tabber.currentWidget().resizeView() @property def tabList(self): diff --git a/src/main/python/utils/dialogs.py b/src/main/python/utils/dialogs.py index 8d5045b..1cd3e0c 100644 --- a/src/main/python/utils/dialogs.py +++ b/src/main/python/utils/dialogs.py @@ -36,7 +36,7 @@ class paperDims(QDialog): dialogBoxLayout.setWidget(1, QFormLayout.LabelRole, ppiLabel) dialogBoxLayout.setWidget(1, QFormLayout.FieldRole, ppiComboBox) self.setLayout(dialogBoxLayout) - self.resize(400,300) #resize to a certain size + self.resize(300,100) #resize to a certain size #todo add ok or cancel buttons -- cgit From 19f5df0a0dff91ca775f7a05aec8d5199b7ca513 Mon Sep 17 00:00:00 2001 From: Blaine Date: Tue, 28 Apr 2020 15:32:21 +0530 Subject: weird --- src/main/python/main.py | 6 +- src/main/python/utils/canvas.py | 173 +++++++++--------------------------- src/main/python/utils/fileWindow.py | 122 +++++++++++++++++++++++++ src/main/python/utils/tabs.py | 6 ++ 4 files changed, 174 insertions(+), 133 deletions(-) create mode 100644 src/main/python/utils/fileWindow.py (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index eb1805a..207701e 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -9,7 +9,8 @@ from PyQt5.QtWidgets import (QComboBox, QFileDialog, QFormLayout, QHBoxLayout, QLabel, QMainWindow, QMenu, QMenuBar, QPushButton, QTabWidget, QWidget, QMdiArea, QMessageBox) -from utils.canvas import canvas, fileWindow +from utils.canvas import canvas +from utils.fileWindow import fileWindow from utils.sizes import ppiList, sheetDimensionList from utils import dialogs @@ -79,8 +80,7 @@ class appWindow(QMainWindow): with open(files,'rb') as file: project = pickle.load(file) self.mdi.addSubWindow(project) - project.show() - project.resizeHandler(self.mdi) + project.show() def saveProject(self): #pickle all files in mdi area diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 696c736..ade0d03 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -2,14 +2,12 @@ import pickle from PyQt5.QtCore import Qt from PyQt5.QtGui import QBrush, QPalette -from PyQt5.QtWidgets import (QFileDialog, QFormLayout, - QGraphicsScene, QGraphicsView, QHBoxLayout, - QMdiSubWindow, QMenu, - QTabWidget, QWidget, QSpacerItem) +from PyQt5.QtWidgets import (QFileDialog, QApplication, + QGraphicsScene, QGraphicsView, QHBoxLayout, QMenu, + QTabWidget, QWidget, QSpacerItem, QStyle) from . import graphics, dialogs from .sizes import paperSizes, ppiList, sheetDimensionList -from .tabs import customTabWidget class canvas(QWidget): """ @@ -33,18 +31,47 @@ class canvas(QWidget): self.view = QGraphicsView(self.painter) #create a viewport for the canvas board self.layout = QHBoxLayout(self) #create the layout of the canvas, the canvas could just subclass QGView instead - self.layout.addWidget(self.view, stretch = 1, alignment= Qt.AlignLeft) - self.spacer = QSpacerItem(1, self.height()) #Horizonatal spacer to force view to not expand to fill widget - self.layout.addSpacerItem(self.spacer) - + self.layout.addWidget(self.view, alignment=Qt.AlignCenter) + # self.spacer = QSpacerItem(1, self.height()) #Horizonatal spacer to force view to not expand to fill widget + # self.layout.addSpacerItem(self.spacer) + # self.layout.addSpacing(0) #set layout and background color - self.setPalette(self.palette) - self.setLayout(self.layout) - - #This is done so that a right click menu is shown on right click - self.setContextMenuPolicy(Qt.CustomContextMenu) - self.customContextMenuRequested.connect(self.contextMenu) + self.setLayout(self.layout) + self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) + # ensure that the scene is always aligned on the left, instead of being + # centered (the default) + # self.view.setAlignment(Qt.AlignLeft|Qt.AlignTop) + + def resizeView(self, w, h): + #helper function to resize canvas + self.painter.setSceneRect(0, 0, w, h) + # self.view.setSceneRect(0, 0, w - self.view.frameWidth() * 2, h) + + def adjustView(self): + #update view size + width, height = self.dimensions + # give the view some time to adjust itself + QApplication.processEvents() + + self.view.setSceneRect(0, 0, width, height) + prect = self.parent().parentWidget().size() + frameWidth = self.view.frameWidth() + width = min(prect.width() - frameWidth*2, width + frameWidth * 2) + height = min(prect.height() - frameWidth*2, height + frameWidth * 2) + + if self.view.verticalScrollBar().isVisible(): + width += self.style().pixelMetric(QStyle.PM_ScrollBarExtent) + if self.view.horizontalScrollBar().isVisible(): + height += self.style().pixelMetric(QStyle.PM_ScrollBarExtent) + self.view.setFixedWidth(width) + self.view.setFixedHeight(height) + self.resize(width + frameWidth * 2, height + frameWidth * 2) + # def resizeEvent(self, event): + # #overloaded function to also view size on window update + # self.adjustView() + # # pass + def setCanvasSize(self, size): """ extended setter for dialog box @@ -80,28 +107,7 @@ class canvas(QWidget): def dimensions(self): #returns the dimension of the current scene return self.painter.sceneRect().width(), self.painter.sceneRect().height() - - def resizeView(self, w=None, h=None): - #resize canvas to appropriate size. - if w is None and h is None: - w, h = paperSizes[self.canvasSize][self.ppi] - self.painter.setSceneRect(0, 0, w, h) - self.view.setSceneRect(0, 0, w, h) - w = min(self.width() - 5, w) - h = self.height() - 5 - self.view.setFixedWidth(w) - self.view.setFixedHeight(h) - - def contextMenu(self, point): - #function to display the right click menu at point of right click - menu = QMenu("Context Menu", self) - menu.addAction("Adjust Canvas", self.adjustCanvasDialog) - menu.exec_(self.mapToGlobal(point)) - def adjustCanvasDialog(self): - #helper function to the context menu dialog box - self.canvasSize, self.ppi = dialogs.paperDims(self, self._canvasSize, self._ppi, self.objectName()).exec_() - #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. def __getstate__(self) -> dict: @@ -123,97 +129,4 @@ class canvas(QWidget): graphic.__setstate__(item) self.painter.addItem(graphic) -class fileWindow(QMdiSubWindow): - """ - This defines a single file, inside the application, consisting of multiple tabs that contain - canvases. Pre-Defined so that a file can be instantly created without defining the structure again. - """ - def __init__(self, parent = None, title = 'New Project', size = 'A4', ppi = '72'): - super(fileWindow, self).__init__(parent) - - #Uses a custom QTabWidget that houses a custom new Tab Button, used to house the seperate - # diagrams inside a file - self.tabber = customTabWidget(self) - self.tabber.setObjectName(title) #store title as object name for pickling - self.tabber.tabCloseRequested.connect(self.closeTab) # Show save alert on tab close - self.tabber.currentChanged.connect(self.changeTab) # placeholder just to detect tab change - self.tabber.plusClicked.connect(self.newDiagram) #connect the new tab button to add a new tab - - #assign layout to widget - self.setWidget(self.tabber) - self.setWindowTitle(title) - - def changeTab(self, currentIndex): - #placeholder function to detect tab change - pass - - def closeTab(self, currentIndex): - #show save alert on tab close - if dialogs.saveEvent(self): - self.tabber.widget(currentIndex).deleteLater() - self.tabber.removeTab(currentIndex) - - def newDiagram(self): - # 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") - self.tabber.addTab(diagram, "New") - diagram.resizeView() - - def resizeHandler(self, parent = None): - # experimental resize Handler to handle resize on parent resize. - parentRect = parent.rect() if parent else self.parent().rect() - self.resize(parentRect.width(), parentRect.height()) - self.setMaximumHeight(parentRect.height()) - self.tabber.setMaximumHeight(parentRect.height()) - for i in self.tabList: - i.setMaximumHeight(parentRect.height()) - self.tabber.currentWidget().resizeView() - - @property - def tabList(self): - #returns a list of tabs in the given window - return [self.tabber.widget(i) for i in range(self.tabCount)] - - @property - def tabCount(self): - #returns the number of tabs in the given window only - return self.tabber.count() - - 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: - with open(name[0],'wb') as file: - pickle.dump(self, file) - return True - else: - return False - - def closeEvent(self, event): - # handle save alert on file close, check if current file has no tabs aswell. - if self.tabCount==0 or dialogs.saveEvent(self): - event.accept() - self.deleteLater() - 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. - def __getstate__(self) -> dict: - 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']) - for i in dict['tabs']: - diagram = canvas(self.tabber, size = dict['canvasSize'], ppi = dict['ppi']) - diagram.__setstate__(i) - self.tabber.addTab(diagram, i['ObjectName']) - - \ No newline at end of file + \ No newline at end of file diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py new file mode 100644 index 0000000..9a679e9 --- /dev/null +++ b/src/main/python/utils/fileWindow.py @@ -0,0 +1,122 @@ +import pickle + +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QMdiSubWindow, QFileDialog, QMenu + +from . import dialogs +from .canvas import canvas +from .tabs import customTabWidget + + +class fileWindow(QMdiSubWindow): + """ + This defines a single file, inside the application, consisting of multiple tabs that contain + canvases. Pre-Defined so that a file can be instantly created without defining the structure again. + """ + def __init__(self, parent = None, title = 'New Project', size = 'A4', ppi = '72'): + super(fileWindow, self).__init__(parent) + + #Uses a custom QTabWidget that houses a custom new Tab Button, used to house the seperate + # diagrams inside a file + self.tabber = customTabWidget(self) + self.tabber.setObjectName(title) #store title as object name for pickling + self.tabber.tabCloseRequested.connect(self.closeTab) # Show save alert on tab close + self.tabber.currentChanged.connect(self.changeTab) # placeholder just to detect tab change + self.tabber.plusClicked.connect(self.newDiagram) #connect the new tab button to add a new tab + # self.tabber.setContentsMargins(0, 1, 1, 1) + #assign layout to widget + self.setWidget(self.tabber) + self.setWindowTitle(title) + + #This is done so that a right click menu is shown on right click + self.setContextMenuPolicy(Qt.CustomContextMenu) + self.customContextMenuRequested.connect(self.contextMenu) + + def changeTab(self, currentIndex): + #placeholder function to detect tab change + self.resizeHandler() + + def closeTab(self, currentIndex): + #show save alert on tab close + if dialogs.saveEvent(self): + self.tabber.widget(currentIndex).deleteLater() + self.tabber.removeTab(currentIndex) + + def newDiagram(self): + # 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") + self.tabber.addTab(diagram, "New") + + def resizeHandler(self, parent = None): + # experimental resize Handler to handle resize on parent resize. + parentRect = parent.rect() if parent else self.parentWidget().rect() + width, height = self.tabber.currentWidget().dimensions + frameWidth = self.tabber.currentWidget().view.frameWidth() + width = min(parentRect.width(), width + frameWidth*2) + height = min(parentRect.height(), height + frameWidth*2) + self.setFixedSize(width, height) + # self.tabber.resize(width, height) + self.tabber.currentWidget().adjustView() + + def contextMenu(self, point): + #function to display the right click menu at point of right click + menu = QMenu("Context Menu", self) + menu.addAction("Adjust Canvas", self.adjustCanvasDialog) + menu.exec_(self.mapToGlobal(point)) + + def adjustCanvasDialog(self): + #helper function to the context menu dialog box + currentTab = self.tabber.currentWidget() + currentTab.canvasSize, currentTab.ppi = dialogs.paperDims(self, currentTab._canvasSize, currentTab._ppi, currentTab.objectName()).exec_() + self.resizeHandler() + + def resizeEvent(self, event): + print(self.size()) + super(fileWindow, self).resizeEvent(event) + + @property + def tabList(self): + #returns a list of tabs in the given window + return [self.tabber.widget(i) for i in range(self.tabCount)] + + @property + def tabCount(self): + #returns the number of tabs in the given window only + return self.tabber.count() + + 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: + with open(name[0],'wb') as file: + pickle.dump(self, file) + return True + else: + return False + + def closeEvent(self, event): + # handle save alert on file close, check if current file has no tabs aswell. + if self.tabCount==0 or dialogs.saveEvent(self): + event.accept() + self.deleteLater() + 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. + def __getstate__(self) -> dict: + 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']) + for i in dict['tabs']: + diagram = canvas(self.tabber, size = dict['canvasSize'], ppi = dict['ppi']) + diagram.__setstate__(i) + self.tabber.addTab(diagram, i['ObjectName']) diff --git a/src/main/python/utils/tabs.py b/src/main/python/utils/tabs.py index 7d8bb1d..7c6319c 100644 --- a/src/main/python/utils/tabs.py +++ b/src/main/python/utils/tabs.py @@ -37,6 +37,12 @@ class customTabWidget(QTabWidget): self.tab.layoutChanged.connect(self.movePlusButton) #connect layout change # to dynamically move the button. + self.setStyleSheet("""QTabWidget::pane { + margin: 0px,1px,1px,1px; + border: 2px solid #E6E6E3; + border-radius: 7px; + padding: 1px; + background-color: #E6E6E3;}""") def movePlusButton(self): #move the new tab button to correct location -- cgit From 4f47a375887aecb2778800f375f4c4e037bf26a6 Mon Sep 17 00:00:00 2001 From: Blaine Date: Tue, 28 Apr 2020 15:42:24 +0530 Subject: typo --- src/main/python/utils/canvas.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index ade0d03..b158b99 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -47,30 +47,31 @@ class canvas(QWidget): #helper function to resize canvas self.painter.setSceneRect(0, 0, w, h) # self.view.setSceneRect(0, 0, w - self.view.frameWidth() * 2, h) + # self.adjustView() def adjustView(self): #update view size width, height = self.dimensions + frameWidth = self.view.frameWidth() + self.view.setSceneRect(0, 0, width - frameWidth*2, height) # give the view some time to adjust itself QApplication.processEvents() - self.view.setSceneRect(0, 0, width, height) - prect = self.parent().parentWidget().size() - frameWidth = self.view.frameWidth() - width = min(prect.width() - frameWidth*2, width + frameWidth * 2) - height = min(prect.height() - frameWidth*2, height + frameWidth * 2) + prect = self.parent().parentWidget().parentWidget().size() + width = width + frameWidth*2 + height = height + frameWidth * 2 if self.view.verticalScrollBar().isVisible(): width += self.style().pixelMetric(QStyle.PM_ScrollBarExtent) if self.view.horizontalScrollBar().isVisible(): height += self.style().pixelMetric(QStyle.PM_ScrollBarExtent) - self.view.setFixedWidth(width) - self.view.setFixedHeight(height) - self.resize(width + frameWidth * 2, height + frameWidth * 2) - # def resizeEvent(self, event): - # #overloaded function to also view size on window update - # self.adjustView() - # # pass + self.view.setFixedWidth(min(prect.width() - frameWidth*2, width)) + self.view.setFixedHeight(min(prect.height() - frameWidth*2, height)) + # self.resize(width + frameWidth * 2, height + frameWidth * 2) + def resizeEvent(self, event): + #overloaded function to also view size on window update + self.adjustView() + # pass def setCanvasSize(self, size): """ -- cgit From a64e5e224d29636a5d9e80b5760da7993d795bcd Mon Sep 17 00:00:00 2001 From: Blaine Date: Tue, 28 Apr 2020 22:27:41 +0530 Subject: The Fix? --- src/main/python/main.py | 3 ++- src/main/python/utils/canvas.py | 12 ++++++------ src/main/python/utils/fileWindow.py | 12 ++++++------ 3 files changed, 14 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 207701e..9fc08bf 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -42,6 +42,7 @@ class appWindow(QMainWindow): mainLayout.setObjectName("Main Layout") 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() @@ -70,7 +71,7 @@ class appWindow(QMainWindow): if not project.tabList: # important when unpickling a file instead project.newDiagram() #create a new tab in the new file project.show() - project.resizeHandler(self.mdi) + project.resizeHandler() def openProject(self): #show the open file dialog to open a saved file, then unpickle it. diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index b158b99..8bac15f 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -55,19 +55,19 @@ class canvas(QWidget): frameWidth = self.view.frameWidth() self.view.setSceneRect(0, 0, width - frameWidth*2, height) # give the view some time to adjust itself - QApplication.processEvents() - prect = self.parent().parentWidget().parentWidget().size() - width = width + frameWidth*2 - height = height + frameWidth * 2 + prect = self.parent().parentWidget().parentWidget().parentWidget().rect() + width = width + 50 + height = height + 100 if self.view.verticalScrollBar().isVisible(): width += self.style().pixelMetric(QStyle.PM_ScrollBarExtent) if self.view.horizontalScrollBar().isVisible(): height += self.style().pixelMetric(QStyle.PM_ScrollBarExtent) - self.view.setFixedWidth(min(prect.width() - frameWidth*2, width)) - self.view.setFixedHeight(min(prect.height() - frameWidth*2, height)) + self.view.setFixedWidth(min(prect.width() - 50, width)) + self.view.setFixedHeight(min(prect.height() - 100, height)) # self.resize(width + frameWidth * 2, height + frameWidth * 2) + def resizeEvent(self, event): #overloaded function to also view size on window update self.adjustView() diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index 9a679e9..929bde0 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -50,11 +50,11 @@ class fileWindow(QMdiSubWindow): def resizeHandler(self, parent = None): # experimental resize Handler to handle resize on parent resize. - parentRect = parent.rect() if parent else self.parentWidget().rect() - width, height = self.tabber.currentWidget().dimensions - frameWidth = self.tabber.currentWidget().view.frameWidth() - width = min(parentRect.width(), width + frameWidth*2) - height = min(parentRect.height(), height + frameWidth*2) + parentRect = parent.parentWidget().rect() if parent else self.parentWidget().parentWidget().rect() + current = self.tabber.currentWidget() + width, height = current.dimensions + width = min(parentRect.width(), width + 50) + height = min(parentRect.height(), height + 100) self.setFixedSize(width, height) # self.tabber.resize(width, height) self.tabber.currentWidget().adjustView() @@ -72,7 +72,7 @@ class fileWindow(QMdiSubWindow): self.resizeHandler() def resizeEvent(self, event): - print(self.size()) + self.resizeHandler() super(fileWindow, self).resizeEvent(event) @property -- cgit From 6d3259d56837b172ce8957fd28c0fa3436066262 Mon Sep 17 00:00:00 2001 From: Blaine Date: Tue, 28 Apr 2020 22:30:01 +0530 Subject: edge case fix --- src/main/python/utils/fileWindow.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index 929bde0..99f1f70 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -53,10 +53,10 @@ class fileWindow(QMdiSubWindow): parentRect = parent.parentWidget().rect() if parent else self.parentWidget().parentWidget().rect() current = self.tabber.currentWidget() width, height = current.dimensions - width = min(parentRect.width(), width + 50) - height = min(parentRect.height(), height + 100) + width = min(parentRect.width(), width + 100) + height = min(parentRect.height(), height + 200) self.setFixedSize(width, height) - # self.tabber.resize(width, height) + self.tabber.resize(width, height) self.tabber.currentWidget().adjustView() def contextMenu(self, point): -- cgit From 6b5859af7ae5097baa2401eb25816cc8a6191a77 Mon Sep 17 00:00:00 2001 From: Blaine Date: Wed, 29 Apr 2020 11:44:33 +0530 Subject: add state change markers --- src/main/python/main.py | 2 +- src/main/python/utils/fileWindow.py | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 9fc08bf..6bd23c4 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -104,7 +104,7 @@ class appWindow(QMainWindow): def resizeEvent(self, event): #overload resize to also handle resize on file windows inside if self.mdi.activeSubWindow(): - self.mdi.activeSubWindow().resizeHandler(self.mdi) + self.mdi.activeSubWindow().resizeHandler() super(appWindow, self).resizeEvent(event) def closeEvent(self, event): diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index 99f1f70..c4cf128 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -32,6 +32,8 @@ class fileWindow(QMdiSubWindow): self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.contextMenu) + self.windowStateChanged.connect(self.stateChange) + def changeTab(self, currentIndex): #placeholder function to detect tab change self.resizeHandler() @@ -48,9 +50,9 @@ class fileWindow(QMdiSubWindow): diagram.setObjectName("New") self.tabber.addTab(diagram, "New") - def resizeHandler(self, parent = None): + def resizeHandler(self): # experimental resize Handler to handle resize on parent resize. - parentRect = parent.parentWidget().rect() if parent else self.parentWidget().parentWidget().rect() + parentRect = self.mdiArea().rect() current = self.tabber.currentWidget() width, height = current.dimensions width = min(parentRect.width(), width + 100) @@ -74,7 +76,18 @@ class fileWindow(QMdiSubWindow): def resizeEvent(self, event): self.resizeHandler() super(fileWindow, self).resizeEvent(event) - + + def stateChange(self, oldState, newState): + if newState == Qt.WindowMinimized: + print("minimized") + elif newState == Qt.WindowFullScreen: + print("maximized") + else: + if oldState == Qt.WindowMinimized: + print("min to full") + else: + print("max to full") + @property def tabList(self): #returns a list of tabs in the given window -- cgit From 2268074e30d34d40a716ede92ef7bf1e1795d958 Mon Sep 17 00:00:00 2001 From: Blaine Date: Wed, 29 Apr 2020 13:39:32 +0530 Subject: create file tab list --- src/main/python/main.py | 21 ++++++++++++++++----- src/main/python/utils/fileWindow.py | 26 ++++++++++++++++---------- 2 files changed, 32 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 6bd23c4..8302b09 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -4,10 +4,9 @@ import sys from fbs_runtime.application_context.PyQt5 import ApplicationContext from PyQt5.QtCore import QObject, Qt, pyqtSignal, pyqtSlot from PyQt5.QtGui import QBrush, QColor, QImage, QPainter, QPalette -from PyQt5.QtWidgets import (QComboBox, QFileDialog, QFormLayout, - QGraphicsScene, QGraphicsView, QGridLayout, +from PyQt5.QtWidgets import (QComboBox, QFileDialog, QFormLayout, QVBoxLayout, QHBoxLayout, QLabel, QMainWindow, QMenu, QMenuBar, - QPushButton, QTabWidget, QWidget, QMdiArea, QMessageBox) + QPushButton, QWidget, QMdiArea, QListWidget) from utils.canvas import canvas from utils.fileWindow import fileWindow @@ -38,8 +37,10 @@ class appWindow(QMainWindow): self.menuGenerate.addAction("Report", self.generateReport) # create new layout for the main widget - mainLayout = QHBoxLayout(self.mainWidget) + mainLayout = QHBoxLayout() mainLayout.setObjectName("Main Layout") + fileLayout = QVBoxLayout() + fileLayout.setObjectName("file window + tabs space") self.mdi = QMdiArea(self) #create area for files to be displayed self.mdi.setObjectName('mdi area') @@ -47,8 +48,13 @@ class appWindow(QMainWindow): #create toolbar and add the toolbar plus mdi to layout self.createToolbar() mainLayout.addWidget(self.toolbar) - mainLayout.addWidget(self.mdi) + fileLayout.addWidget(self.mdi) + self.createTabSpace() + fileLayout.addWidget(self.tabSpace) + + mainLayout.addLayout(fileLayout) + #declare main window layout self.mainWidget.setLayout(mainLayout) self.setCentralWidget(self.mainWidget) @@ -63,6 +69,11 @@ class appWindow(QMainWindow): toolbarLayout = QFormLayout(self.toolbar) self.toolbar.setLayout(toolbarLayout) + def createTabSpace(self): + self.tabSpace = QListWidget(self.mainWidget) + self.tabSpace.setFlow(QListWidget.LeftToRight) + self.tabSpace.setFixedHeight(25) + def newProject(self): #call to create a new file inside mdi area project = fileWindow(self.mdi) diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index c4cf128..26aa165 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -1,7 +1,7 @@ import pickle from PyQt5.QtCore import Qt -from PyQt5.QtWidgets import QMdiSubWindow, QFileDialog, QMenu +from PyQt5.QtWidgets import QMdiSubWindow, QFileDialog, QMenu, QSizePolicy from . import dialogs from .canvas import canvas @@ -16,6 +16,7 @@ class fileWindow(QMdiSubWindow): def __init__(self, parent = None, title = 'New Project', size = 'A4', ppi = '72'): super(fileWindow, self).__init__(parent) + 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 self.tabber = customTabWidget(self) @@ -48,8 +49,9 @@ class fileWindow(QMdiSubWindow): # 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") - self.tabber.addTab(diagram, "New") - + index = self.tabber.addTab(diagram, "New") + self.tabber.setCurrentIndex(index) + def resizeHandler(self): # experimental resize Handler to handle resize on parent resize. parentRect = self.mdiArea().rect() @@ -74,19 +76,23 @@ class fileWindow(QMdiSubWindow): self.resizeHandler() def resizeEvent(self, event): - self.resizeHandler() - super(fileWindow, self).resizeEvent(event) + # self.resizeHandler() + # super(fileWindow, self).resizeEvent(event) + pass def stateChange(self, oldState, newState): + areaRect = self.mdiArea().rect() if newState == Qt.WindowMinimized: - print("minimized") - elif newState == Qt.WindowFullScreen: - print("maximized") + pass + elif newState == Qt.WindowMaximized: + pass else: if oldState == Qt.WindowMinimized: - print("min to full") + # print("min to full") + pass else: - print("max to full") + # print("max to full") + pass @property def tabList(self): -- cgit From d772066ac2a8f440990eba0632cf77b168d8849d Mon Sep 17 00:00:00 2001 From: Blaine Date: Wed, 29 Apr 2020 16:19:42 +0530 Subject: file dock working --- src/main/python/main.py | 42 ++++++++++++++++++++++++++++--------- src/main/python/utils/fileWindow.py | 29 ++++++++++++------------- 2 files changed, 47 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 8302b09..8bed5b3 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -2,10 +2,10 @@ import pickle import sys from fbs_runtime.application_context.PyQt5 import ApplicationContext -from PyQt5.QtCore import QObject, Qt, pyqtSignal, pyqtSlot +from PyQt5.QtCore import QObject, Qt, pyqtSignal from PyQt5.QtGui import QBrush, QColor, QImage, QPainter, QPalette from PyQt5.QtWidgets import (QComboBox, QFileDialog, QFormLayout, QVBoxLayout, - QHBoxLayout, QLabel, QMainWindow, QMenu, QMenuBar, + QHBoxLayout, QLabel, QMainWindow, QMenu, QTabBar, QPushButton, QWidget, QMdiArea, QListWidget) from utils.canvas import canvas @@ -13,7 +13,6 @@ from utils.fileWindow import fileWindow from utils.sizes import ppiList, sheetDimensionList from utils import dialogs - class appWindow(QMainWindow): """ Application entry point, subclasses QMainWindow and implements the main widget, @@ -44,7 +43,6 @@ class appWindow(QMainWindow): 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() mainLayout.addWidget(self.toolbar) @@ -60,6 +58,7 @@ class appWindow(QMainWindow): self.setCentralWidget(self.mainWidget) self.resize(1280, 720) #set collapse dim self.setWindowState(Qt.WindowMaximized) #launch maximized + self.mdi.subWindowActivated.connect(lambda x: self.tabSpace.setCurrentIndex(x.index) if (x is not None) else False) def createToolbar(self): #place holder for toolbar with fixed width, layout may change @@ -70,9 +69,17 @@ class appWindow(QMainWindow): self.toolbar.setLayout(toolbarLayout) def createTabSpace(self): - self.tabSpace = QListWidget(self.mainWidget) - self.tabSpace.setFlow(QListWidget.LeftToRight) + self.tabSpace = QTabBar(self.mainWidget) + # self.tabSpace.setFlow(QListWidget.LeftToRight) self.tabSpace.setFixedHeight(25) + self.tabSpace.currentChanged.connect(self.switchProject) + self.tabSpace.setVisible(False) + + def switchProject(self, index): + i = self.mdi.subWindowList(order=QMdiArea.CreationOrder)[index] + if not i.isVisible(): + i.show() + self.mdi.setActiveSubWindow(i) def newProject(self): #call to create a new file inside mdi area @@ -81,9 +88,12 @@ 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.show() project.resizeHandler() - + project.fileCloseEvent.connect(self.fileClosed) + project.index = self.tabSpace.addTab("New Project") + if self.tabSpace.count() > 1: + self.tabSpace.setVisible(True) + def openProject(self): #show the open file dialog to open a saved file, then unpickle it. name = QFileDialog.getOpenFileNames(self, 'Open File(s)', '', 'Process Flow Diagram (*pfd)') @@ -92,8 +102,12 @@ class appWindow(QMainWindow): with open(files,'rb') as file: project = pickle.load(file) self.mdi.addSubWindow(project) - project.show() - + project.show() + project.resizeHandler() + project.fileCloseEvent.connect(self.fileClosed) + if self.tabSpace.count() > 1: + self.tabSpace.setVisible(True) + def saveProject(self): #pickle all files in mdi area for j, i in enumerate(self.mdi.activeFiles): #get list of all windows with atleast one tab @@ -125,6 +139,14 @@ class appWindow(QMainWindow): else: event.accept() + def fileClosed(self, index): + self.tabSpace.removeTab(index) + i = self.mdi.subWindowList(order=QMdiArea.CreationOrder)[self.tabSpace.currentIndex()] + i.show() + self.mdi.setActiveSubWindow(i) + if self.tabSpace.count() <=1 : + self.tabSpace.setVisible(False) + @property def activeFiles(self): return [i for i in self.mdi.subWindowList() if i.tabCount] diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index 26aa165..1e8258d 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -1,22 +1,24 @@ import pickle -from PyQt5.QtCore import Qt +from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtWidgets import QMdiSubWindow, QFileDialog, QMenu, QSizePolicy from . import dialogs from .canvas import canvas from .tabs import customTabWidget - class fileWindow(QMdiSubWindow): """ This defines a single file, inside the application, consisting of multiple tabs that contain canvases. Pre-Defined so that a file can be instantly created without defining the structure again. """ + fileCloseEvent = pyqtSignal(int) + fileMinimized = pyqtSignal(int) def __init__(self, parent = None, title = 'New Project', size = 'A4', ppi = '72'): super(fileWindow, self).__init__(parent) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) + self.index = None #Uses a custom QTabWidget that houses a custom new Tab Button, used to house the seperate # diagrams inside a file self.tabber = customTabWidget(self) @@ -77,22 +79,20 @@ class fileWindow(QMdiSubWindow): def resizeEvent(self, event): # self.resizeHandler() - # super(fileWindow, self).resizeEvent(event) - pass + super(fileWindow, self).resizeEvent(event) + # pass def stateChange(self, oldState, newState): - areaRect = self.mdiArea().rect() if newState == Qt.WindowMinimized: - pass - elif newState == Qt.WindowMaximized: - pass + self.hide() else: - if oldState == Qt.WindowMinimized: - # print("min to full") - pass - else: - # print("max to full") - pass + if not self.isVisible(): + self.show() + if newState == Qt.WindowMaximized: + self.setFixedSize(self.mdiArea().size()) + + def showShaded(self): + self.hide() @property def tabList(self): @@ -119,6 +119,7 @@ class fileWindow(QMdiSubWindow): if self.tabCount==0 or dialogs.saveEvent(self): event.accept() self.deleteLater() + self.fileCloseEvent.emit(self.index) else: event.ignore() -- cgit From 8024803c29b85e87a0e65eedfd1c8c1975be074c Mon Sep 17 00:00:00 2001 From: Blaine Date: Thu, 30 Apr 2020 14:18:22 +0530 Subject: implement tabbed view --- src/main/python/main.py | 59 ++++++++++++++++++------------------------------- 1 file changed, 22 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 8bed5b3..059bb63 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -5,8 +5,8 @@ from fbs_runtime.application_context.PyQt5 import ApplicationContext from PyQt5.QtCore import QObject, Qt, pyqtSignal from PyQt5.QtGui import QBrush, QColor, QImage, QPainter, QPalette from PyQt5.QtWidgets import (QComboBox, QFileDialog, QFormLayout, QVBoxLayout, - QHBoxLayout, QLabel, QMainWindow, QMenu, QTabBar, - QPushButton, QWidget, QMdiArea, QListWidget) + QHBoxLayout, QLabel, QMainWindow, QMenu, + QPushButton, QWidget, QMdiArea) from utils.canvas import canvas from utils.fileWindow import fileWindow @@ -38,27 +38,24 @@ class appWindow(QMainWindow): # create new layout for the main widget mainLayout = QHBoxLayout() mainLayout.setObjectName("Main Layout") - fileLayout = QVBoxLayout() - fileLayout.setObjectName("file window + tabs space") 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() mainLayout.addWidget(self.toolbar) + mainLayout.addWidget(self.mdi) - fileLayout.addWidget(self.mdi) - self.createTabSpace() - fileLayout.addWidget(self.tabSpace) + self.mdi.setOption(QMdiArea.DontMaximizeSubWindowOnActivation, True) #set flag so that window doesnt look weird + self.mdi.setTabsClosable(True) + self.mdi.setTabsMovable(True) + self.mdi.setDocumentMode(True) - mainLayout.addLayout(fileLayout) - #declare main window layout self.mainWidget.setLayout(mainLayout) self.setCentralWidget(self.mainWidget) self.resize(1280, 720) #set collapse dim - self.setWindowState(Qt.WindowMaximized) #launch maximized - self.mdi.subWindowActivated.connect(lambda x: self.tabSpace.setCurrentIndex(x.index) if (x is not None) else False) + self.setWindowState(Qt.WindowMaximized) #launch maximized def createToolbar(self): #place holder for toolbar with fixed width, layout may change @@ -66,20 +63,7 @@ class appWindow(QMainWindow): self.toolbar.setObjectName("Toolbar") self.toolbar.setFixedWidth(200) toolbarLayout = QFormLayout(self.toolbar) - self.toolbar.setLayout(toolbarLayout) - - def createTabSpace(self): - self.tabSpace = QTabBar(self.mainWidget) - # self.tabSpace.setFlow(QListWidget.LeftToRight) - self.tabSpace.setFixedHeight(25) - self.tabSpace.currentChanged.connect(self.switchProject) - self.tabSpace.setVisible(False) - - def switchProject(self, index): - i = self.mdi.subWindowList(order=QMdiArea.CreationOrder)[index] - if not i.isVisible(): - i.show() - self.mdi.setActiveSubWindow(i) + self.toolbar.setLayout(toolbarLayout) def newProject(self): #call to create a new file inside mdi area @@ -89,10 +73,10 @@ class appWindow(QMainWindow): 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) - project.index = self.tabSpace.addTab("New Project") - if self.tabSpace.count() > 1: - self.tabSpace.setVisible(True) + 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) + project.show() def openProject(self): #show the open file dialog to open a saved file, then unpickle it. @@ -105,8 +89,9 @@ class appWindow(QMainWindow): project.show() project.resizeHandler() project.fileCloseEvent.connect(self.fileClosed) - if self.tabSpace.count() > 1: - self.tabSpace.setVisible(True) + if self.count > 1: + # self.tabSpace.setVisible(True) + self.mdi.setViewMode(QMdiArea.TabbedView) def saveProject(self): #pickle all files in mdi area @@ -140,17 +125,17 @@ class appWindow(QMainWindow): event.accept() def fileClosed(self, index): - self.tabSpace.removeTab(index) - i = self.mdi.subWindowList(order=QMdiArea.CreationOrder)[self.tabSpace.currentIndex()] - i.show() - self.mdi.setActiveSubWindow(i) - if self.tabSpace.count() <=1 : - self.tabSpace.setVisible(False) + if self.count <= 2 : + self.mdi.setViewMode(QMdiArea.SubWindowView) @property def activeFiles(self): return [i for i in self.mdi.subWindowList() if i.tabCount] + @property + def count(self): + return len(self.mdi.subWindowList()) + if __name__ == '__main__': app = ApplicationContext() # 1. Instantiate ApplicationContext test = appWindow() -- cgit From c6c699b2c231616b17625d355ec269b1a51809a5 Mon Sep 17 00:00:00 2001 From: Blaine Date: Thu, 30 Apr 2020 14:18:45 +0530 Subject: implement ok and cancel on adjust canvas dialog --- src/main/python/utils/canvas.py | 2 ++ src/main/python/utils/dialogs.py | 11 ++++++++--- src/main/python/utils/fileWindow.py | 13 +++++++++---- 3 files changed, 19 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 8bac15f..8bbe99b 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -35,6 +35,8 @@ class canvas(QWidget): # self.spacer = QSpacerItem(1, self.height()) #Horizonatal spacer to force view to not expand to fill widget # self.layout.addSpacerItem(self.spacer) # self.layout.addSpacing(0) + self.layout.setContentsMargins(0, 0, 0 ,0) + self.layout.setSpacing(0) #set layout and background color self.setLayout(self.layout) diff --git a/src/main/python/utils/dialogs.py b/src/main/python/utils/dialogs.py index 1cd3e0c..83a5f90 100644 --- a/src/main/python/utils/dialogs.py +++ b/src/main/python/utils/dialogs.py @@ -1,4 +1,4 @@ -from PyQt5.QtWidgets import QDialog, QPushButton, QFormLayout, QComboBox, QLabel, QMessageBox +from PyQt5.QtWidgets import QDialog, QPushButton, QFormLayout, QComboBox, QLabel, QMessageBox, QDialogButtonBox from .sizes import sheetDimensionList, ppiList class paperDims(QDialog): @@ -35,6 +35,12 @@ class paperDims(QDialog): ppiComboBox.setCurrentIndex(ppiList.index(self._ppi)) #set index to current value of canvas dialogBoxLayout.setWidget(1, QFormLayout.LabelRole, ppiLabel) dialogBoxLayout.setWidget(1, QFormLayout.FieldRole, ppiComboBox) + + buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self) + buttonBox.accepted.connect(self.accept) + buttonBox.rejected.connect(self.reject) + + dialogBoxLayout.addWidget(buttonBox) self.setLayout(dialogBoxLayout) self.resize(300,100) #resize to a certain size @@ -51,8 +57,7 @@ class paperDims(QDialog): def exec_(self): #overload exec_ to add return values and delete itself(currently being tested) super(paperDims, self).exec_() - # self.deleteLater() - return self._canvasSize, self._ppi + return self._canvasSize, self._ppi if self.result==1 else None def saveEvent(parent = None): #utility function to generate a Qt alert window requesting the user to save the file, returns user intention on window close diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index 1e8258d..bab9004 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -13,7 +13,6 @@ class fileWindow(QMdiSubWindow): canvases. Pre-Defined so that a file can be instantly created without defining the structure again. """ fileCloseEvent = pyqtSignal(int) - fileMinimized = pyqtSignal(int) def __init__(self, parent = None, title = 'New Project', size = 'A4', ppi = '72'): super(fileWindow, self).__init__(parent) @@ -37,6 +36,8 @@ class fileWindow(QMdiSubWindow): self.windowStateChanged.connect(self.stateChange) + self.setAttribute(Qt.WA_DeleteOnClose, True) + def changeTab(self, currentIndex): #placeholder function to detect tab change self.resizeHandler() @@ -56,7 +57,7 @@ class fileWindow(QMdiSubWindow): def resizeHandler(self): # experimental resize Handler to handle resize on parent resize. - parentRect = self.mdiArea().rect() + parentRect = self.mdiArea().sizeHint() current = self.tabber.currentWidget() width, height = current.dimensions width = min(parentRect.width(), width + 100) @@ -74,8 +75,12 @@ class fileWindow(QMdiSubWindow): def adjustCanvasDialog(self): #helper function to the context menu dialog box currentTab = self.tabber.currentWidget() - currentTab.canvasSize, currentTab.ppi = dialogs.paperDims(self, currentTab._canvasSize, currentTab._ppi, currentTab.objectName()).exec_() - self.resizeHandler() + result = dialogs.paperDims(self, currentTab._canvasSize, currentTab._ppi, currentTab.objectName()).exec_() + if result: + currentTab.canvasSize, currentTab.ppi = result + return self.resizeHandler() + else: + return None def resizeEvent(self, event): # self.resizeHandler() -- cgit From 3d75d12cb5f90b3af03e7408cbdb805426485a1c Mon Sep 17 00:00:00 2001 From: Blaine Date: Thu, 30 Apr 2020 14:29:36 +0530 Subject: small dialog box fix --- src/main/python/utils/dialogs.py | 14 +++++++++++++- src/main/python/utils/fileWindow.py | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/dialogs.py b/src/main/python/utils/dialogs.py index 83a5f90..d5522cc 100644 --- a/src/main/python/utils/dialogs.py +++ b/src/main/python/utils/dialogs.py @@ -57,7 +57,19 @@ class paperDims(QDialog): def exec_(self): #overload exec_ to add return values and delete itself(currently being tested) super(paperDims, self).exec_() - return self._canvasSize, self._ppi if self.result==1 else None + self.deleteLater() + return (self._canvasSize, self._ppi) if self.result() else None + + def accept(self): + self.setResult(1) + self.accepted.emit() + return super(paperDims, self).accept() + + def reject(self): + self.setResult(0) + self.rejected.emit() + return super(paperDims, self).reject() + def saveEvent(parent = None): #utility function to generate a Qt alert window requesting the user to save the file, returns user intention on window close diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index bab9004..d5ad19f 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -76,7 +76,7 @@ class fileWindow(QMdiSubWindow): #helper function to the context menu dialog box currentTab = self.tabber.currentWidget() result = dialogs.paperDims(self, currentTab._canvasSize, currentTab._ppi, currentTab.objectName()).exec_() - if result: + if result is not None: currentTab.canvasSize, currentTab.ppi = result return self.resizeHandler() else: -- cgit From 8d479352c448247be8b7e080048dd588094d98b0 Mon Sep 17 00:00:00 2001 From: Blaine Date: Thu, 30 Apr 2020 16:07:33 +0530 Subject: rebase --- src/main/python/main.py | 7 ++++++- src/main/python/utils/canvas.py | 16 ++++++---------- src/main/python/utils/fileWindow.py | 35 +++++++++++++++++------------------ src/main/python/utils/tabs.py | 1 + 4 files changed, 30 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 059bb63..5971403 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -74,6 +74,7 @@ class appWindow(QMainWindow): 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 + project.fileMinimized.connect(self.fileMinimized) if self.count > 1: #switch to tab view if needed self.mdi.setViewMode(QMdiArea.TabbedView) project.show() @@ -127,7 +128,11 @@ class appWindow(QMainWindow): def fileClosed(self, index): if self.count <= 2 : self.mdi.setViewMode(QMdiArea.SubWindowView) - + + def fileMinimized(self, file): + if self.count > 1: + self.mdi.activateNextSubWindow() + @property def activeFiles(self): return [i for i in self.mdi.subWindowList() if i.tabCount] diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 8bbe99b..2c99ff2 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -32,11 +32,7 @@ class canvas(QWidget): self.layout = QHBoxLayout(self) #create the layout of the canvas, the canvas could just subclass QGView instead self.layout.addWidget(self.view, alignment=Qt.AlignCenter) - # self.spacer = QSpacerItem(1, self.height()) #Horizonatal spacer to force view to not expand to fill widget - # self.layout.addSpacerItem(self.spacer) - # self.layout.addSpacing(0) - self.layout.setContentsMargins(0, 0, 0 ,0) - self.layout.setSpacing(0) + self.layout.setContentsMargins(0, 0, 0, 0) #set layout and background color self.setLayout(self.layout) @@ -54,20 +50,20 @@ class canvas(QWidget): def adjustView(self): #update view size width, height = self.dimensions - frameWidth = self.view.frameWidth() + frameWidth = self.view.frameWidth() self.view.setSceneRect(0, 0, width - frameWidth*2, height) # give the view some time to adjust itself prect = self.parent().parentWidget().parentWidget().parentWidget().rect() - width = width + 50 - height = height + 100 + width = width + 20 + height = height + 60 if self.view.verticalScrollBar().isVisible(): width += self.style().pixelMetric(QStyle.PM_ScrollBarExtent) if self.view.horizontalScrollBar().isVisible(): height += self.style().pixelMetric(QStyle.PM_ScrollBarExtent) - self.view.setFixedWidth(min(prect.width() - 50, width)) - self.view.setFixedHeight(min(prect.height() - 100, height)) + self.view.setFixedWidth(min(prect.width() - 20, width)) + self.view.setFixedHeight(min(prect.height() - 60, height)) # self.resize(width + frameWidth * 2, height + frameWidth * 2) def resizeEvent(self, event): diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index d5ad19f..fd2bc11 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -13,6 +13,7 @@ class fileWindow(QMdiSubWindow): canvases. Pre-Defined so that a file can be instantly created without defining the structure again. """ fileCloseEvent = pyqtSignal(int) + fileMinimized = pyqtSignal(QMdiSubWindow) def __init__(self, parent = None, title = 'New Project', size = 'A4', ppi = '72'): super(fileWindow, self).__init__(parent) @@ -57,7 +58,7 @@ class fileWindow(QMdiSubWindow): def resizeHandler(self): # experimental resize Handler to handle resize on parent resize. - parentRect = self.mdiArea().sizeHint() + parentRect = self.mdiArea().size() current = self.tabber.currentWidget() width, height = current.dimensions width = min(parentRect.width(), width + 100) @@ -82,23 +83,21 @@ class fileWindow(QMdiSubWindow): else: return None - def resizeEvent(self, event): - # self.resizeHandler() - super(fileWindow, self).resizeEvent(event) - # pass - - def stateChange(self, oldState, newState): - if newState == Qt.WindowMinimized: - self.hide() - else: - if not self.isVisible(): - self.show() - if newState == Qt.WindowMaximized: - self.setFixedSize(self.mdiArea().size()) - - def showShaded(self): - self.hide() - + # def stateChange(self, oldState, newState): + # if newState == Qt.WindowMinimized: + # print("a") + # self.setVisible(False) + # elif newState == Qt.WindowMaximized: + # print("b") + # parentRect = self.mdiArea().size() + # self.setFixedSize(parentRect.width(), parentRect.height()) + # self.tabber.resize(parentRect.width(), parentRect.height()) + # self.tabber.currentWidget().adjustView() + # else: + # if oldState == Qt.WindowMinimized or oldState == Qt.WindowMaximized: + # print("c") + # self.resizeHandler() + @property def tabList(self): #returns a list of tabs in the given window diff --git a/src/main/python/utils/tabs.py b/src/main/python/utils/tabs.py index 7c6319c..037710c 100644 --- a/src/main/python/utils/tabs.py +++ b/src/main/python/utils/tabs.py @@ -43,6 +43,7 @@ class customTabWidget(QTabWidget): border-radius: 7px; padding: 1px; background-color: #E6E6E3;}""") + self.setContentsMargins(0, 0, 0, 0) def movePlusButton(self): #move the new tab button to correct location -- cgit From 3a5155d2ec9455ba474fc1f4d55f65f02dfd54f6 Mon Sep 17 00:00:00 2001 From: Blaine Date: Thu, 30 Apr 2020 18:51:19 +0530 Subject: remove minimize and maximize from file window --- src/main/python/utils/fileWindow.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index fd2bc11..ae5ff85 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -35,9 +35,12 @@ class fileWindow(QMdiSubWindow): self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.contextMenu) - self.windowStateChanged.connect(self.stateChange) + # self.windowStateChanged.connect(self.stateChange) self.setAttribute(Qt.WA_DeleteOnClose, True) + self.setWindowFlag(Qt.CustomizeWindowHint, True) + self.setWindowFlag(Qt.WindowMinimizeButtonHint, False) + self.setWindowFlag(Qt.WindowMaximizeButtonHint, False) def changeTab(self, currentIndex): #placeholder function to detect tab change @@ -63,6 +66,8 @@ class fileWindow(QMdiSubWindow): width, height = current.dimensions width = min(parentRect.width(), width + 100) height = min(parentRect.height(), height + 200) + # width = parentRect.width() + # height = parentRect.height() self.setFixedSize(width, height) self.tabber.resize(width, height) self.tabber.currentWidget().adjustView() -- cgit From 0f9e183d9f174888dd4c15922e5a038a6467afc2 Mon Sep 17 00:00:00 2001 From: Blaine Date: Fri, 1 May 2020 14:30:08 +0530 Subject: implement side view widget --- src/main/python/main.py | 2 +- src/main/python/utils/canvas.py | 16 +++++-- src/main/python/utils/fileWindow.py | 89 +++++++++++++++++++++++-------------- 3 files changed, 69 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 5971403..abdb822 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -55,7 +55,7 @@ class appWindow(QMainWindow): self.mainWidget.setLayout(mainLayout) self.setCentralWidget(self.mainWidget) self.resize(1280, 720) #set collapse dim - self.setWindowState(Qt.WindowMaximized) #launch maximized + # self.setWindowState(Qt.WindowMaximized) #launch maximized def createToolbar(self): #place holder for toolbar with fixed width, layout may change diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 2c99ff2..418a95e 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -33,13 +33,16 @@ class canvas(QWidget): self.layout = QHBoxLayout(self) #create the layout of the canvas, the canvas could just subclass QGView instead self.layout.addWidget(self.view, alignment=Qt.AlignCenter) self.layout.setContentsMargins(0, 0, 0, 0) - #set layout and background color self.setLayout(self.layout) + #set layout and background color self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) # ensure that the scene is always aligned on the left, instead of being # centered (the default) # self.view.setAlignment(Qt.AlignLeft|Qt.AlignTop) + + self.parentMdiArea = self.parent().parentWidget().parentWidget().parentWidget().parentWidget() + self.parentFileWindow = self.parent().parentWidget().parentWidget() def resizeView(self, w, h): #helper function to resize canvas @@ -54,7 +57,8 @@ class canvas(QWidget): self.view.setSceneRect(0, 0, width - frameWidth*2, height) # give the view some time to adjust itself - prect = self.parent().parentWidget().parentWidget().parentWidget().rect() + prect = self.parentMdiArea.rect() + # prect = self.parent().parent().size() width = width + 20 height = height + 60 @@ -62,8 +66,12 @@ class canvas(QWidget): width += self.style().pixelMetric(QStyle.PM_ScrollBarExtent) if self.view.horizontalScrollBar().isVisible(): height += self.style().pixelMetric(QStyle.PM_ScrollBarExtent) - self.view.setFixedWidth(min(prect.width() - 20, width)) - self.view.setFixedHeight(min(prect.height() - 60, height)) + + # factor = 2 if self.parentFileWindow.sideViewTab is not None else 1 + width = min(prect.width() - 20, width) # // factor + height = min(prect.height() - 60, height) # // factor + self.view.setFixedWidth(width) + self.view.setFixedHeight(height) # self.resize(width + frameWidth * 2, height + frameWidth * 2) def resizeEvent(self, event): diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index ae5ff85..6b3c754 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -1,7 +1,7 @@ import pickle from PyQt5.QtCore import Qt, pyqtSignal -from PyQt5.QtWidgets import QMdiSubWindow, QFileDialog, QMenu, QSizePolicy +from PyQt5.QtWidgets import QMdiSubWindow, QFileDialog, QMenu, QSizePolicy, QWidget, QHBoxLayout, QSplitter, QGraphicsView from . import dialogs from .canvas import canvas @@ -16,9 +16,10 @@ class fileWindow(QMdiSubWindow): fileMinimized = pyqtSignal(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.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) - self.index = None #Uses a custom QTabWidget that houses a custom new Tab Button, used to house the seperate # diagrams inside a file self.tabber = customTabWidget(self) @@ -26,22 +27,29 @@ class fileWindow(QMdiSubWindow): self.tabber.tabCloseRequested.connect(self.closeTab) # Show save alert on tab close self.tabber.currentChanged.connect(self.changeTab) # placeholder just to detect tab change self.tabber.plusClicked.connect(self.newDiagram) #connect the new tab button to add a new tab - # self.tabber.setContentsMargins(0, 1, 1, 1) + #assign layout to widget - self.setWidget(self.tabber) + self.mainWidget = QWidget(self) + layout = QHBoxLayout(self.mainWidget) + layout.addWidget(self.tabber) + self.splitter = QSplitter(Qt.Vertical ,self) + layout.addWidget(self.splitter) + self.sideView = QGraphicsView(self) + layout.addWidget(self.sideView) + + self.mainWidget.setLayout(layout) + self.setWidget(self.mainWidget) self.setWindowTitle(title) #This is done so that a right click menu is shown on right click self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.contextMenu) - # self.windowStateChanged.connect(self.stateChange) - self.setAttribute(Qt.WA_DeleteOnClose, True) self.setWindowFlag(Qt.CustomizeWindowHint, True) self.setWindowFlag(Qt.WindowMinimizeButtonHint, False) self.setWindowFlag(Qt.WindowMaximizeButtonHint, False) - + def changeTab(self, currentIndex): #placeholder function to detect tab change self.resizeHandler() @@ -64,20 +72,18 @@ class fileWindow(QMdiSubWindow): parentRect = self.mdiArea().size() current = self.tabber.currentWidget() width, height = current.dimensions - width = min(parentRect.width(), width + 100) - height = min(parentRect.height(), height + 200) + if self.sideViewTab: + width = parentRect.width() + height = parentRect.height() + else: + width = min(parentRect.width(), width + 100) + height = min(parentRect.height(), height + 200) # width = parentRect.width() # height = parentRect.height() self.setFixedSize(width, height) self.tabber.resize(width, height) self.tabber.currentWidget().adjustView() - - def contextMenu(self, point): - #function to display the right click menu at point of right click - menu = QMenu("Context Menu", self) - menu.addAction("Adjust Canvas", self.adjustCanvasDialog) - menu.exec_(self.mapToGlobal(point)) - + def adjustCanvasDialog(self): #helper function to the context menu dialog box currentTab = self.tabber.currentWidget() @@ -88,21 +94,38 @@ class fileWindow(QMdiSubWindow): else: return None - # def stateChange(self, oldState, newState): - # if newState == Qt.WindowMinimized: - # print("a") - # self.setVisible(False) - # elif newState == Qt.WindowMaximized: - # print("b") - # parentRect = self.mdiArea().size() - # self.setFixedSize(parentRect.width(), parentRect.height()) - # self.tabber.resize(parentRect.width(), parentRect.height()) - # self.tabber.currentWidget().adjustView() - # else: - # if oldState == Qt.WindowMinimized or oldState == Qt.WindowMaximized: - # print("c") - # self.resizeHandler() - + def contextMenu(self, point): + #function to display the right click menu at point of right click + menu = QMenu("Context Menu", self) + menu.addAction("Adjust Canvas", self.adjustCanvasDialog) + menu.addAction("View Side-By-Side", self.sideViewMode) + menu.exec_(self.mapToGlobal(point)) + + def sideViewMode(self): + self.sideViewTab = self.tabber.currentWidget() + + def sideViewToggle(self): + 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) + self.sideView.setVisible(False) + self.resizeHandler() + return False + + @property + def sideViewTab(self): + return self._sideViewTab + + @sideViewTab.setter + def sideViewTab(self, tab): + self._sideViewTab = None if tab == self.sideViewTab else tab + return self.sideViewToggle() + @property def tabList(self): #returns a list of tabs in the given window @@ -146,6 +169,6 @@ class fileWindow(QMdiSubWindow): def __setstate__(self, dict): self.__init__(title = dict['ObjectName']) for i in dict['tabs']: - diagram = canvas(self.tabber, size = dict['canvasSize'], ppi = dict['ppi']) + diagram = canvas(self.tabber, size = dict['canvasSize'], ppi = dict['ppi'], fileWindow = self) diagram.__setstate__(i) self.tabber.addTab(diagram, i['ObjectName']) -- cgit From d2dd2117a260f188cc3d0bacc2a6b863bcd973c0 Mon Sep 17 00:00:00 2001 From: Blaine Date: Fri, 1 May 2020 15:08:17 +0530 Subject: hecc --- src/main/python/utils/canvas.py | 6 +++--- src/main/python/utils/fileWindow.py | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 418a95e..2ddcc01 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -67,9 +67,9 @@ class canvas(QWidget): if self.view.horizontalScrollBar().isVisible(): height += self.style().pixelMetric(QStyle.PM_ScrollBarExtent) - # factor = 2 if self.parentFileWindow.sideViewTab is not None else 1 - width = min(prect.width() - 20, width) # // factor - height = min(prect.height() - 60, height) # // factor + factor = 2 if self.parentFileWindow.sideViewTab is not None else 1 + width = min((prect.width() - 20)//factor, width) + height = min(prect.height() - 80, height) self.view.setFixedWidth(width) self.view.setFixedHeight(height) # self.resize(width + frameWidth * 2, height + frameWidth * 2) diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index 6b3c754..f9b3ac5 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -50,6 +50,9 @@ class fileWindow(QMdiSubWindow): self.setWindowFlag(Qt.WindowMinimizeButtonHint, False) self.setWindowFlag(Qt.WindowMaximizeButtonHint, False) + self.splitter.setVisible(False) + self.sideView.setVisible(False) + def changeTab(self, currentIndex): #placeholder function to detect tab change self.resizeHandler() -- cgit From 06816626c9ef691303012008dfae09b0210f78a1 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 2 May 2020 14:25:03 +0530 Subject: refactor and cleanup --- src/main/python/main.py | 11 ++--- src/main/python/utils/canvas.py | 33 +++++++-------- src/main/python/utils/dialogs.py | 17 ++------ src/main/python/utils/fileWindow.py | 83 ++++++++++++++++++++----------------- src/main/python/utils/tabs.py | 3 +- 5 files changed, 70 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index abdb822..83cbffd 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -41,12 +41,14 @@ class appWindow(QMainWindow): 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() mainLayout.addWidget(self.toolbar) mainLayout.addWidget(self.mdi) - self.mdi.setOption(QMdiArea.DontMaximizeSubWindowOnActivation, True) #set flag so that window doesnt look weird + #set flag so that window doesnt look weird + self.mdi.setOption(QMdiArea.DontMaximizeSubWindowOnActivation, True) self.mdi.setTabsClosable(True) self.mdi.setTabsMovable(True) self.mdi.setDocumentMode(True) @@ -55,7 +57,6 @@ class appWindow(QMainWindow): self.mainWidget.setLayout(mainLayout) self.setCentralWidget(self.mainWidget) self.resize(1280, 720) #set collapse dim - # self.setWindowState(Qt.WindowMaximized) #launch maximized def createToolbar(self): #place holder for toolbar with fixed width, layout may change @@ -74,7 +75,6 @@ class appWindow(QMainWindow): 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 - project.fileMinimized.connect(self.fileMinimized) if self.count > 1: #switch to tab view if needed self.mdi.setViewMode(QMdiArea.TabbedView) project.show() @@ -126,12 +126,9 @@ class appWindow(QMainWindow): event.accept() def fileClosed(self, index): + #checks if the file tab menu needs to be removed if self.count <= 2 : self.mdi.setViewMode(QMdiArea.SubWindowView) - - def fileMinimized(self, file): - if self.count > 1: - self.mdi.activateNextSubWindow() @property def activeFiles(self): diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 2ddcc01..8f5f7b4 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -36,48 +36,47 @@ class canvas(QWidget): self.setLayout(self.layout) #set layout and background color + #set initial paper size for the scene self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) - # ensure that the scene is always aligned on the left, instead of being - # centered (the default) - # self.view.setAlignment(Qt.AlignLeft|Qt.AlignTop) + #set pointers to necessary parents for ease of reference self.parentMdiArea = self.parent().parentWidget().parentWidget().parentWidget().parentWidget() self.parentFileWindow = self.parent().parentWidget().parentWidget() def resizeView(self, w, h): #helper function to resize canvas self.painter.setSceneRect(0, 0, w, h) - # self.view.setSceneRect(0, 0, w - self.view.frameWidth() * 2, h) - # self.adjustView() def adjustView(self): - #update view size + #utitily to adjust current diagram view width, height = self.dimensions frameWidth = self.view.frameWidth() - self.view.setSceneRect(0, 0, width - frameWidth*2, height) - # give the view some time to adjust itself - + #update view size + self.view.setSceneRect(0, 0, width - frameWidth*2, height) + + # use the available mdi area, also add padding prect = self.parentMdiArea.rect() - # prect = self.parent().parent().size() width = width + 20 height = height + 60 + # add scrollbar size to width and height if they are visible, avoids clipping if self.view.verticalScrollBar().isVisible(): width += self.style().pixelMetric(QStyle.PM_ScrollBarExtent) if self.view.horizontalScrollBar().isVisible(): height += self.style().pixelMetric(QStyle.PM_ScrollBarExtent) + #if view is visible use half of available width factor = 2 if self.parentFileWindow.sideViewTab is not None else 1 + #use minimum width required to fit the view width = min((prect.width() - 20)//factor, width) height = min(prect.height() - 80, height) + #set view dims self.view.setFixedWidth(width) self.view.setFixedHeight(height) - # self.resize(width + frameWidth * 2, height + frameWidth * 2) def resizeEvent(self, event): #overloaded function to also view size on window update self.adjustView() - # pass def setCanvasSize(self, size): """ @@ -91,6 +90,11 @@ class canvas(QWidget): """ self.ppi = ppi + @property + def dimensions(self): + #returns the dimension of the current scene + return self.painter.sceneRect().width(), self.painter.sceneRect().height() + @property def canvasSize(self): return self._canvasSize @@ -109,11 +113,6 @@ class canvas(QWidget): self._ppi = ppi if self.painter: self.resizeView(*paperSizes[self.canvasSize][self.ppi]) - - @property - def dimensions(self): - #returns the dimension of the current scene - return self.painter.sceneRect().width(), self.painter.sceneRect().height() #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. diff --git a/src/main/python/utils/dialogs.py b/src/main/python/utils/dialogs.py index d5522cc..4970468 100644 --- a/src/main/python/utils/dialogs.py +++ b/src/main/python/utils/dialogs.py @@ -36,6 +36,7 @@ class paperDims(QDialog): dialogBoxLayout.setWidget(1, QFormLayout.LabelRole, ppiLabel) dialogBoxLayout.setWidget(1, QFormLayout.FieldRole, ppiComboBox) + # add ok and cancel buttons buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) @@ -43,8 +44,6 @@ class paperDims(QDialog): dialogBoxLayout.addWidget(buttonBox) self.setLayout(dialogBoxLayout) self.resize(300,100) #resize to a certain size - - #todo add ok or cancel buttons def setCanvasSize(self, size): #for standard combo box behaviour @@ -57,20 +56,10 @@ class paperDims(QDialog): def exec_(self): #overload exec_ to add return values and delete itself(currently being tested) super(paperDims, self).exec_() - self.deleteLater() + self.deleteLater() #remove from memory + #if ok was pressed return value else return None return (self._canvasSize, self._ppi) if self.result() else None - - def accept(self): - self.setResult(1) - self.accepted.emit() - return super(paperDims, self).accept() - - def reject(self): - self.setResult(0) - self.rejected.emit() - return super(paperDims, self).reject() - def saveEvent(parent = None): #utility function to generate a Qt alert window requesting the user to save the file, returns user intention on window close alert = QMessageBox.question(parent, parent.objectName(), "All unsaved progress will be LOST!", diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index f9b3ac5..c850b27 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -13,7 +13,7 @@ class fileWindow(QMdiSubWindow): canvases. Pre-Defined so that a file can be instantly created without defining the structure again. """ fileCloseEvent = pyqtSignal(int) - fileMinimized = pyqtSignal(QMdiSubWindow) + def __init__(self, parent = None, title = 'New Project', size = 'A4', ppi = '72'): super(fileWindow, self).__init__(parent) self._sideViewTab = None @@ -53,61 +53,49 @@ class fileWindow(QMdiSubWindow): self.splitter.setVisible(False) self.sideView.setVisible(False) - def changeTab(self, currentIndex): - #placeholder function to detect tab change - self.resizeHandler() - - def closeTab(self, currentIndex): - #show save alert on tab close - if dialogs.saveEvent(self): - self.tabber.widget(currentIndex).deleteLater() - self.tabber.removeTab(currentIndex) - - def newDiagram(self): - # 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") - self.tabber.setCurrentIndex(index) - def resizeHandler(self): - # experimental resize Handler to handle resize on parent resize. + # resize Handler to handle resize cases. parentRect = self.mdiArea().size() current = self.tabber.currentWidget() width, height = current.dimensions + + # if side view is visible, set width to maximum possible, else use minimum requirement if self.sideViewTab: width = parentRect.width() height = parentRect.height() else: width = min(parentRect.width(), width + 100) height = min(parentRect.height(), height + 200) - # width = parentRect.width() - # height = parentRect.height() + + # set element dimensions self.setFixedSize(width, height) self.tabber.resize(width, height) self.tabber.currentWidget().adjustView() - - def adjustCanvasDialog(self): - #helper function to the context menu dialog box - currentTab = self.tabber.currentWidget() - result = dialogs.paperDims(self, currentTab._canvasSize, currentTab._ppi, currentTab.objectName()).exec_() - if result is not None: - currentTab.canvasSize, currentTab.ppi = result - return self.resizeHandler() - else: - return None def contextMenu(self, point): #function to display the right click menu at point of right click menu = QMenu("Context Menu", self) menu.addAction("Adjust Canvas", self.adjustCanvasDialog) - menu.addAction("View Side-By-Side", self.sideViewMode) + menu.addAction("Remove Side View" if self.sideViewTab == self.tabber.currentWidget() else "View Side-By-Side", + self.sideViewMode) menu.exec_(self.mapToGlobal(point)) - def sideViewMode(self): + def sideViewMode(self): + #helper context menu function to toggle side view self.sideViewTab = self.tabber.currentWidget() + def adjustCanvasDialog(self): + #helper context menu function to the context menu dialog box + currentTab = self.tabber.currentWidget() + result = dialogs.paperDims(self, currentTab._canvasSize, currentTab._ppi, currentTab.objectName()).exec_() + if result is not None: + currentTab.canvasSize, currentTab.ppi = result + return self.resizeHandler() + else: + return None + 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) @@ -122,13 +110,9 @@ class fileWindow(QMdiSubWindow): @property def sideViewTab(self): + #returns current active if sideViewTab otherwise None return self._sideViewTab - @sideViewTab.setter - def sideViewTab(self, tab): - self._sideViewTab = None if tab == self.sideViewTab else tab - return self.sideViewToggle() - @property def tabList(self): #returns a list of tabs in the given window @@ -139,6 +123,29 @@ class fileWindow(QMdiSubWindow): #returns the number of tabs in the given window only return self.tabber.count() + @sideViewTab.setter + def sideViewTab(self, tab): + #setter for side view. Also toggles view as necessary + self._sideViewTab = None if tab == self.sideViewTab else tab + return self.sideViewToggle() + + def changeTab(self, currentIndex): + #placeholder function to detect tab change + self.resizeHandler() + + def closeTab(self, currentIndex): + #show save alert on tab close + if dialogs.saveEvent(self): + self.tabber.widget(currentIndex).deleteLater() + self.tabber.removeTab(currentIndex) + + def newDiagram(self): + # 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") + self.tabber.setCurrentIndex(index) + 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 diff --git a/src/main/python/utils/tabs.py b/src/main/python/utils/tabs.py index 037710c..1049ce5 100644 --- a/src/main/python/utils/tabs.py +++ b/src/main/python/utils/tabs.py @@ -37,13 +37,14 @@ class customTabWidget(QTabWidget): self.tab.layoutChanged.connect(self.movePlusButton) #connect layout change # to dynamically move the button. + + #set custom stylesheet for the widget area self.setStyleSheet("""QTabWidget::pane { margin: 0px,1px,1px,1px; border: 2px solid #E6E6E3; border-radius: 7px; padding: 1px; background-color: #E6E6E3;}""") - self.setContentsMargins(0, 0, 0, 0) def movePlusButton(self): #move the new tab button to correct location -- cgit From 61725f4a541ad956295c3fa425d26bf9bd0aa008 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 2 May 2020 15:46:10 +0530 Subject: typos fixed --- src/main/python/main.py | 2 +- src/main/python/utils/canvas.py | 5 +++-- src/main/python/utils/fileWindow.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 83cbffd..a61d230 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -47,7 +47,7 @@ class appWindow(QMainWindow): mainLayout.addWidget(self.toolbar) mainLayout.addWidget(self.mdi) - #set flag so that window doesnt look weird + #set flags so that window doesnt look weird self.mdi.setOption(QMdiArea.DontMaximizeSubWindowOnActivation, True) self.mdi.setTabsClosable(True) self.mdi.setTabsMovable(True) diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 8f5f7b4..bf035f1 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -24,7 +24,9 @@ class canvas(QWidget): self._canvasSize = size # self.setFixedSize(parent.size()) #Create area for the graphic items to be placed, this is just here right now for the future - # when we will draw items on this, this might be changed if QGraphicScene is subclassed. + # when we will draw items on this, this might be changed if QGraphicScene is subclassed. + + #set layout and background color self.painter = QGraphicsScene() self.painter.setBackgroundBrush(QBrush(Qt.white)) #set white background @@ -34,7 +36,6 @@ class canvas(QWidget): self.layout.addWidget(self.view, alignment=Qt.AlignCenter) self.layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.layout) - #set layout and background color #set initial paper size for the scene self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index c850b27..22bbc68 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -45,7 +45,7 @@ class fileWindow(QMdiSubWindow): self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.contextMenu) - self.setAttribute(Qt.WA_DeleteOnClose, True) + # self.setAttribute(Qt.WA_DeleteOnClose, True) self.setWindowFlag(Qt.CustomizeWindowHint, True) self.setWindowFlag(Qt.WindowMinimizeButtonHint, False) self.setWindowFlag(Qt.WindowMaximizeButtonHint, False) -- cgit From e7ca3971e9412d41076a6c36b7fb829447ef0b3b Mon Sep 17 00:00:00 2001 From: Blaine Date: Mon, 4 May 2020 15:26:27 +0530 Subject: mino fixes and floating close button --- src/main/python/main.py | 16 +++++++++++----- src/main/python/utils/fileWindow.py | 38 +++++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index a61d230..647792b 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -51,13 +51,14 @@ class appWindow(QMainWindow): self.mdi.setOption(QMdiArea.DontMaximizeSubWindowOnActivation, True) self.mdi.setTabsClosable(True) self.mdi.setTabsMovable(True) - self.mdi.setDocumentMode(True) + self.mdi.setDocumentMode(False) #declare main window layout self.mainWidget.setLayout(mainLayout) self.setCentralWidget(self.mainWidget) self.resize(1280, 720) #set collapse dim - + self.mdi.subWindowActivated.connect(self.tabSwitched) + def createToolbar(self): #place holder for toolbar with fixed width, layout may change self.toolbar = QWidget(self.mainWidget) @@ -96,7 +97,7 @@ class appWindow(QMainWindow): def saveProject(self): #pickle all files in mdi area - for j, i in enumerate(self.mdi.activeFiles): #get list of all windows with atleast one tab + 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)') i.saveProject(name) @@ -112,10 +113,15 @@ class appWindow(QMainWindow): #place holder for future implementaion pass + def tabSwitched(self, window): + #handle window switched edge case + if window: + window.resizeHandler() + def resizeEvent(self, event): #overload resize to also handle resize on file windows inside - if self.mdi.activeSubWindow(): - self.mdi.activeSubWindow().resizeHandler() + for i in self.mdi.subWindowList(): + i.resizeHandler() super(appWindow, self).resizeEvent(event) def closeEvent(self, event): diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index 22bbc68..fdf1c11 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -1,12 +1,16 @@ import pickle from PyQt5.QtCore import Qt, pyqtSignal -from PyQt5.QtWidgets import QMdiSubWindow, QFileDialog, QMenu, QSizePolicy, QWidget, QHBoxLayout, QSplitter, QGraphicsView +from PyQt5.QtGui import QIcon +from PyQt5.QtWidgets import (QFileDialog, QGraphicsView, QHBoxLayout, + QMdiSubWindow, QMenu, QPushButton, QSizePolicy, + QSplitter, QWidget) from . import dialogs from .canvas import canvas from .tabs import customTabWidget + class fileWindow(QMdiSubWindow): """ This defines a single file, inside the application, consisting of multiple tabs that contain @@ -31,12 +35,10 @@ class fileWindow(QMdiSubWindow): #assign layout to widget self.mainWidget = QWidget(self) layout = QHBoxLayout(self.mainWidget) + self.createSideViewArea() #create the side view objects layout.addWidget(self.tabber) - self.splitter = QSplitter(Qt.Vertical ,self) layout.addWidget(self.splitter) - self.sideView = QGraphicsView(self) layout.addWidget(self.sideView) - self.mainWidget.setLayout(layout) self.setWidget(self.mainWidget) self.setWindowTitle(title) @@ -50,6 +52,30 @@ class fileWindow(QMdiSubWindow): self.setWindowFlag(Qt.WindowMinimizeButtonHint, False) self.setWindowFlag(Qt.WindowMaximizeButtonHint, False) + def createSideViewArea(self): + #creates the side view widgets and sets them to invisible + self.splitter = QSplitter(Qt.Vertical ,self) + self.sideView = QGraphicsView(self) + self.sideView.setInteractive(False) + sideViewCloseButton = QPushButton('×', self.sideView) + sideViewCloseButton.setFlat(True) + sideViewCloseButton.setStyleSheet("""QPushButton{ + background: rgba(214, 54, 40, 50%); + border: 1px groove white; + border-radius: 2px; + font-size: 18px; + font-weight: Bold; + padding: 1px 2px 3px 3px; + color: rgba(255, 255, 255, 50%); + } + QPushButton:Hover{ + background: rgba(214, 54, 40, 90%); + color: rgba(255, 255, 255, 90%); + } + """) + sideViewCloseButton.setFixedSize(20, 20) + sideViewCloseButton.move(5, 5) + sideViewCloseButton.clicked.connect(lambda: setattr(self, 'sideViewTab', None)) self.splitter.setVisible(False) self.sideView.setVisible(False) @@ -67,10 +93,14 @@ class fileWindow(QMdiSubWindow): width = min(parentRect.width(), width + 100) height = min(parentRect.height(), height + 200) + if len(self.parent().parent().subWindowList()) > 1: + height -= 20 + # set element dimensions self.setFixedSize(width, height) self.tabber.resize(width, height) self.tabber.currentWidget().adjustView() + def contextMenu(self, point): #function to display the right click menu at point of right click -- cgit From 700edf250bdcc90638fd3aed21ccb67ef60f086b Mon Sep 17 00:00:00 2001 From: Blaine Date: Tue, 5 May 2020 11:42:14 +0530 Subject: transparent backgroun --- src/main/python/utils/tabs.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main/python/utils/tabs.py b/src/main/python/utils/tabs.py index 1049ce5..d42a8c9 100644 --- a/src/main/python/utils/tabs.py +++ b/src/main/python/utils/tabs.py @@ -28,6 +28,15 @@ class customTabWidget(QTabWidget): self.setTabBar(self.tab) #set tabBar to our custom tabBarPlus self.plusButton = QPushButton('+', self) #create the new tab button + #style the new tab button + self.plusButton.setFlat(True) + self.plusButton.setStyleSheet("""QPushButton{ + background: rgba(230, 230, 227, 0%); + } + QPushButton:Hover{ + background: rgba(230, 230, 227, 40%); + }""") + #and parent it to the widget to add it at 0, 0 self.plusButton.setFixedSize(35, 25) #set dimensions self.plusButton.clicked.connect(self.plusClicked.emit) #emit signal on click @@ -50,7 +59,7 @@ class customTabWidget(QTabWidget): #move the new tab button to correct location size = sum([self.tab.tabRect(i).width() for i in range(self.tab.count())]) # calculate width of all tabs - h = max(self.tab.geometry().bottom() - 25, 0) #align with bottom of tabbar + h = max(self.tab.geometry().bottom() - self.plusButton.height(), 0) #align with bottom of tabbar w = self.tab.width() if size > w: #if all the tabs do not overflow the tab bar, add at the end self.plusButton.move(w-self.plusButton.width(), h) -- cgit From c169f11c3f7d887cc956d291e224046e1b75fbe4 Mon Sep 17 00:00:00 2001 From: Blaine Date: Tue, 5 May 2020 11:42:26 +0530 Subject: added splitter --- src/main/python/main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 647792b..3addc68 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -6,7 +6,7 @@ from PyQt5.QtCore import QObject, Qt, pyqtSignal from PyQt5.QtGui import QBrush, QColor, QImage, QPainter, QPalette from PyQt5.QtWidgets import (QComboBox, QFileDialog, QFormLayout, QVBoxLayout, QHBoxLayout, QLabel, QMainWindow, QMenu, - QPushButton, QWidget, QMdiArea) + QPushButton, QWidget, QMdiArea, QSplitter) from utils.canvas import canvas from utils.fileWindow import fileWindow @@ -45,6 +45,7 @@ class appWindow(QMainWindow): #create toolbar and add the toolbar plus mdi to layout self.createToolbar() mainLayout.addWidget(self.toolbar) + mainLayout.addWidget(QSplitter(Qt.Vertical, self)) mainLayout.addWidget(self.mdi) #set flags so that window doesnt look weird -- cgit From 7fa23828f14322e7c34fc32b7e9c6ac5d688200e Mon Sep 17 00:00:00 2001 From: Blaine Date: Tue, 5 May 2020 13:45:48 +0530 Subject: some keyboard shortcuts --- src/main/python/main.py | 42 +++++++++++++++++++++++++++++++++++++ src/main/python/utils/canvas.py | 5 +++++ src/main/python/utils/fileWindow.py | 3 +-- 3 files changed, 48 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 3addc68..56e29e3 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -145,6 +145,48 @@ class appWindow(QMainWindow): def count(self): return len(self.mdi.subWindowList()) + #Key input handler + def keyPressEvent(self, event): + #overload key press event for custom keyboard shortcuts + if event.modifiers() and Qt.ControlModifier: + if event.key() == Qt.key_N: + self.newProject() + + elif event.key() == Qt.Key_S: + self.saveProject() + + elif event.key() == Qt.Key_O: + self.openProject() + + elif event.key() == Qt.Key_Q: + self.closeEvent() + + elif event.key() == Qt.Key_P: + if Qt.AltModifier: + self.saveImage() + else: + self.generateReport() + + elif event.key() == Qt.key_A: + #todo implement selectAll + for item in self.mdi.activeSubWindow().tabber.currentWidget().items: + item.setSelected(True) + + #todo copy, paste, undo redo + + else: + return event.reject() + + elif event.key() == Qt.Key_Delete or event.key() == Qt.Key_Backspace: + for item in self.mdi.activeSubWindow().tabber.currentWidget().painter.selectedItems(): + item.setEnabled(False) + #donot delete, to manage undo redo + + else: + return event.reject() + + return event.accept() + if __name__ == '__main__': app = ApplicationContext() # 1. Instantiate ApplicationContext test = appWindow() diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index bf035f1..e2e6ab8 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -95,6 +95,11 @@ 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 + for i in self.painter.items(): + yield i @property def canvasSize(self): diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index fdf1c11..26daf46 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -100,8 +100,7 @@ class fileWindow(QMdiSubWindow): self.setFixedSize(width, height) self.tabber.resize(width, height) self.tabber.currentWidget().adjustView() - - + def contextMenu(self, point): #function to display the right click menu at point of right click menu = QMenu("Context Menu", self) -- cgit From 708835a4859a0c5d81a34b26442962e727a0035b Mon Sep 17 00:00:00 2001 From: Blaine Date: Tue, 5 May 2020 14:26:43 +0530 Subject: return values fixed, and edge case sorted --- src/main/python/main.py | 13 ++++--------- src/main/python/utils/fileWindow.py | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 56e29e3..81e54e1 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -149,7 +149,7 @@ class appWindow(QMainWindow): def keyPressEvent(self, event): #overload key press event for custom keyboard shortcuts if event.modifiers() and Qt.ControlModifier: - if event.key() == Qt.key_N: + if event.key() == Qt.Key_N: self.newProject() elif event.key() == Qt.Key_S: @@ -159,7 +159,7 @@ class appWindow(QMainWindow): self.openProject() elif event.key() == Qt.Key_Q: - self.closeEvent() + self.close() elif event.key() == Qt.Key_P: if Qt.AltModifier: @@ -167,25 +167,20 @@ class appWindow(QMainWindow): else: self.generateReport() - elif event.key() == Qt.key_A: + elif event.key() == Qt.Key_A: #todo implement selectAll for item in self.mdi.activeSubWindow().tabber.currentWidget().items: item.setSelected(True) #todo copy, paste, undo redo - else: - return event.reject() elif event.key() == Qt.Key_Delete or event.key() == Qt.Key_Backspace: for item in self.mdi.activeSubWindow().tabber.currentWidget().painter.selectedItems(): item.setEnabled(False) #donot delete, to manage undo redo - - else: - return event.reject() - return event.accept() + event.accept() if __name__ == '__main__': app = ApplicationContext() # 1. Instantiate ApplicationContext diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index 26daf46..95488b0 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -178,7 +178,7 @@ class fileWindow(QMdiSubWindow): 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: + if name[0]: with open(name[0],'wb') as file: pickle.dump(self, file) return True -- cgit From 97b304ea746d3ad380fa1ac31409cadc4dbb139b Mon Sep 17 00:00:00 2001 From: Blaine Date: Wed, 6 May 2020 16:51:02 +0530 Subject: scroll wheel init --- src/main/python/main.py | 2 +- src/main/python/utils/canvas.py | 4 ++-- src/main/python/utils/graphics.py | 16 +++++++++++++++- src/main/python/utils/tabs.py | 10 +++++++--- 4 files changed, 25 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 81e54e1..fc4c145 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -158,7 +158,7 @@ class appWindow(QMainWindow): elif event.key() == Qt.Key_O: self.openProject() - elif event.key() == Qt.Key_Q: + elif event.key() == Qt.Key_W: self.close() elif event.key() == Qt.Key_P: diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index e2e6ab8..640d4cc 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -30,7 +30,7 @@ class canvas(QWidget): self.painter = QGraphicsScene() self.painter.setBackgroundBrush(QBrush(Qt.white)) #set white background - self.view = QGraphicsView(self.painter) #create a viewport for the canvas board + self.view = graphics.customView(self.painter, self) #create a viewport for the canvas board self.layout = QHBoxLayout(self) #create the layout of the canvas, the canvas could just subclass QGView instead self.layout.addWidget(self.view, alignment=Qt.AlignCenter) @@ -69,7 +69,7 @@ class canvas(QWidget): #if view is visible use half of available width factor = 2 if self.parentFileWindow.sideViewTab is not None else 1 #use minimum width required to fit the view - width = min((prect.width() - 20)//factor, width) + width = min((prect.width() - 40)//factor, width) height = min(prect.height() - 80, height) #set view dims self.view.setFixedWidth(width) diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py index fc80254..9e1f690 100644 --- a/src/main/python/utils/graphics.py +++ b/src/main/python/utils/graphics.py @@ -1 +1,15 @@ -pass \ No newline at end of file +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QGraphicsView +class customView(QGraphicsView): + + def __init__(self, scene, parent=None): + super(customView, self).__init__(scene, parent) + self.zoom = 1 + + def wheelEvent(self, QWheelEvent): + if Qt.ControlModifier: + self.zoom += QWheelEvent.angleDelta().y()/2880 + self.scale(self.zoom, self.zoom) + QWheelEvent.accept() + else: + return super().wheelEvent(self, QWheelEvent) \ No newline at end of file diff --git a/src/main/python/utils/tabs.py b/src/main/python/utils/tabs.py index d42a8c9..eab056a 100644 --- a/src/main/python/utils/tabs.py +++ b/src/main/python/utils/tabs.py @@ -30,11 +30,15 @@ class customTabWidget(QTabWidget): self.plusButton = QPushButton('+', self) #create the new tab button #style the new tab button self.plusButton.setFlat(True) - self.plusButton.setStyleSheet("""QPushButton{ + self.plusButton.setStyleSheet(""" + QPushButton{ background: rgba(230, 230, 227, 0%); + padding: 1px; + border: 0px solid #E6E6E3; + } - QPushButton:Hover{ - background: rgba(230, 230, 227, 40%); + QPushButton:hover{ + background: rgba(230, 230, 227, 60%); }""") #and parent it to the widget to add it at 0, 0 -- cgit From ecb94d6b121d0c3c9d79dc58140535432cfef973 Mon Sep 17 00:00:00 2001 From: Blaine Date: Wed, 6 May 2020 18:24:38 +0530 Subject: Fix zoom in zoom out --- src/main/python/utils/canvas.py | 5 +++-- src/main/python/utils/fileWindow.py | 41 +++++++++++++++++++++++-------------- src/main/python/utils/graphics.py | 19 +++++++++++++---- 3 files changed, 44 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 640d4cc..a4c56f3 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -6,7 +6,8 @@ from PyQt5.QtWidgets import (QFileDialog, QApplication, QGraphicsScene, QGraphicsView, QHBoxLayout, QMenu, QTabWidget, QWidget, QSpacerItem, QStyle) -from . import graphics, dialogs +from . import dialogs +from .graphics import customView from .sizes import paperSizes, ppiList, sheetDimensionList class canvas(QWidget): @@ -30,7 +31,7 @@ class canvas(QWidget): self.painter = QGraphicsScene() self.painter.setBackgroundBrush(QBrush(Qt.white)) #set white background - self.view = graphics.customView(self.painter, self) #create a viewport for the canvas board + self.view = customView(self.painter, self) #create a viewport for the canvas board self.layout = QHBoxLayout(self) #create the layout of the canvas, the canvas could just subclass QGView instead self.layout.addWidget(self.view, alignment=Qt.AlignCenter) diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index 95488b0..24d6a6d 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -2,11 +2,12 @@ import pickle from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtGui import QIcon -from PyQt5.QtWidgets import (QFileDialog, QGraphicsView, QHBoxLayout, +from PyQt5.QtWidgets import (QFileDialog, QHBoxLayout, QMdiSubWindow, QMenu, QPushButton, QSizePolicy, - QSplitter, QWidget) + QSplitter, QWidget, QStyle) from . import dialogs +from .graphics import customView from .canvas import canvas from .tabs import customTabWidget @@ -55,11 +56,11 @@ class fileWindow(QMdiSubWindow): def createSideViewArea(self): #creates the side view widgets and sets them to invisible self.splitter = QSplitter(Qt.Vertical ,self) - self.sideView = QGraphicsView(self) + self.sideView = customView(parent = self) self.sideView.setInteractive(False) - sideViewCloseButton = QPushButton('×', self.sideView) - sideViewCloseButton.setFlat(True) - sideViewCloseButton.setStyleSheet("""QPushButton{ + self.sideViewCloseButton = QPushButton('×', self.sideView) + self.sideViewCloseButton.setFlat(True) + self.sideViewCloseButton.setStyleSheet("""QPushButton{ background: rgba(214, 54, 40, 50%); border: 1px groove white; border-radius: 2px; @@ -67,15 +68,15 @@ class fileWindow(QMdiSubWindow): font-weight: Bold; padding: 1px 2px 3px 3px; color: rgba(255, 255, 255, 50%); - } - QPushButton:Hover{ - background: rgba(214, 54, 40, 90%); - color: rgba(255, 255, 255, 90%); - } + } + QPushButton:Hover{ + background: rgba(214, 54, 40, 90%); + color: rgba(255, 255, 255, 90%); + } """) - sideViewCloseButton.setFixedSize(20, 20) - sideViewCloseButton.move(5, 5) - sideViewCloseButton.clicked.connect(lambda: setattr(self, 'sideViewTab', None)) + self.sideViewCloseButton.setFixedSize(20, 20) + self.moveSideViewCloseButton() + self.sideViewCloseButton.clicked.connect(lambda: setattr(self, 'sideViewTab', None)) self.splitter.setVisible(False) self.sideView.setVisible(False) @@ -89,6 +90,8 @@ class fileWindow(QMdiSubWindow): if self.sideViewTab: width = parentRect.width() height = parentRect.height() + self.moveSideViewCloseButton() + else: width = min(parentRect.width(), width + 100) height = min(parentRect.height(), height + 200) @@ -129,6 +132,7 @@ class fileWindow(QMdiSubWindow): self.splitter.setVisible(True) self.sideView.setVisible(True) self.sideView.setScene(self.tabber.currentWidget().painter) + self.moveSideViewCloseButton() self.resizeHandler() return True else: @@ -136,7 +140,14 @@ class fileWindow(QMdiSubWindow): self.sideView.setVisible(False) self.resizeHandler() return False - + + def moveSideViewCloseButton(self): + x = self.sideView.width() - 5 + print(x) + if self.sideView.verticalScrollBar().isVisible(): + x -= self.style().pixelMetric(QStyle.PM_ScrollBarExtent) + self.sideViewCloseButton.move(x, 5) + @property def sideViewTab(self): #returns current active if sideViewTab otherwise None diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py index 9e1f690..aed7eed 100644 --- a/src/main/python/utils/graphics.py +++ b/src/main/python/utils/graphics.py @@ -1,15 +1,26 @@ from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QGraphicsView + class customView(QGraphicsView): - def __init__(self, scene, parent=None): - super(customView, self).__init__(scene, parent) + def __init__(self, scene = None, parent=None): + if scene is not None: + super(customView, self).__init__(scene, parent) + else: + super(customView, self).__init__(parent) self.zoom = 1 + self.setDragMode(True) def wheelEvent(self, QWheelEvent): if Qt.ControlModifier: - self.zoom += QWheelEvent.angleDelta().y()/2880 - self.scale(self.zoom, self.zoom) + temp = self.zoom + if QWheelEvent.source() == Qt.MouseEventNotSynthesized: + if self.zoom + QWheelEvent.angleDelta().y()/2880 > 0.1: + self.zoom += QWheelEvent.angleDelta().y()/2880 + else: + if self.zoom + QWheelEvent.pixelDelta().y() > 0.1: + self.zoom += QWheelEvent.angleDelta().y() + self.scale(self.zoom / temp, self.zoom / temp) QWheelEvent.accept() else: return super().wheelEvent(self, QWheelEvent) \ No newline at end of file -- cgit From 6c5a39579c737d0054e29403ec0a045cc6a6d52a Mon Sep 17 00:00:00 2001 From: Blaine Date: Wed, 6 May 2020 20:39:07 +0530 Subject: revert close button move --- src/main/python/utils/fileWindow.py | 10 +++++----- src/main/python/utils/graphics.py | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index 24d6a6d..2fb6abb 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -142,11 +142,11 @@ class fileWindow(QMdiSubWindow): return False def moveSideViewCloseButton(self): - x = self.sideView.width() - 5 - print(x) - if self.sideView.verticalScrollBar().isVisible(): - x -= self.style().pixelMetric(QStyle.PM_ScrollBarExtent) - self.sideViewCloseButton.move(x, 5) + # x = self.rect().width()//2 - 5 + # if self.sideView.verticalScrollBar().isVisible(): + # x -= self.style().pixelMetric(QStyle.PM_ScrollBarExtent) + # self.sideViewCloseButton.move(x, 5) + self.sideViewCloseButton.move(5, 5) @property def sideViewTab(self): diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py index aed7eed..8c87b96 100644 --- a/src/main/python/utils/graphics.py +++ b/src/main/python/utils/graphics.py @@ -8,19 +8,27 @@ class customView(QGraphicsView): super(customView, self).__init__(scene, parent) else: super(customView, self).__init__(parent) - self.zoom = 1 + self._zoom = 1 self.setDragMode(True) def wheelEvent(self, QWheelEvent): if Qt.ControlModifier: - temp = self.zoom if QWheelEvent.source() == Qt.MouseEventNotSynthesized: if self.zoom + QWheelEvent.angleDelta().y()/2880 > 0.1: self.zoom += QWheelEvent.angleDelta().y()/2880 else: if self.zoom + QWheelEvent.pixelDelta().y() > 0.1: self.zoom += QWheelEvent.angleDelta().y() - self.scale(self.zoom / temp, self.zoom / temp) QWheelEvent.accept() else: - return super().wheelEvent(self, QWheelEvent) \ No newline at end of file + return super().wheelEvent(self, QWheelEvent) + + @property + def zoom(self): + return self._zoom + + @zoom.setter + def zoom(self, value): + temp = self.zoom + self._zoom = value + self.scale(self.zoom / temp, self.zoom / temp) \ No newline at end of file -- cgit From 47ab33d71bec2e099b0bd6a432b3cbae067f4bba Mon Sep 17 00:00:00 2001 From: Blaine Date: Thu, 7 May 2020 13:08:08 +0530 Subject: added context menu plus dialog to side view tab --- src/main/python/utils/dialogs.py | 34 ++++++++++++++++++++++++++++++++++ src/main/python/utils/fileWindow.py | 27 ++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/dialogs.py b/src/main/python/utils/dialogs.py index 4970468..8ab8f6f 100644 --- a/src/main/python/utils/dialogs.py +++ b/src/main/python/utils/dialogs.py @@ -59,7 +59,41 @@ class paperDims(QDialog): self.deleteLater() #remove from memory #if ok was pressed return value else return None return (self._canvasSize, self._ppi) if self.result() else None + +class sideViewSwitchDialog(QDialog): + + def __init__(self, parent=None, tabList = None, initial = None): + super(sideViewSwitchDialog, self).__init__(parent=parent) + self.tabList = tabList + self.returnVal = initial + self.initial = initial + + dialogBoxLayout = QFormLayout(self) + tabListComboBox = QComboBox() + tabListComboBox.addItems(self.tabList) + tabListComboBox.activated[str].connect(lambda x: setattr(self, 'returnVal', self.tabList.index(x))) + tabLabel = QLabel("Change Side View") + tabLabel.setBuddy(tabListComboBox) # label for the above combo box + tabListComboBox.setCurrentIndex(self.returnVal) + dialogBoxLayout.setWidget(1, QFormLayout.LabelRole, tabLabel) + dialogBoxLayout.setWidget(1, QFormLayout.FieldRole, tabListComboBox) + + # add ok and cancel buttons + buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self) + buttonBox.accepted.connect(self.accept) + buttonBox.rejected.connect(self.reject) + dialogBoxLayout.addWidget(buttonBox) + self.setLayout(dialogBoxLayout) + self.resize(300,100) #resize to a certain size + + def exec_(self): + #overload exec_ to add return values and delete itself(currently being tested) + super(sideViewSwitchDialog, self).exec_() + self.deleteLater() #remove from memory + #if ok was pressed return value else return None + return self.returnVal if self.result() else self.initial + def saveEvent(parent = None): #utility function to generate a Qt alert window requesting the user to save the file, returns user intention on window close alert = QMessageBox.question(parent, parent.objectName(), "All unsaved progress will be LOST!", diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index 2fb6abb..1c53c86 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -1,6 +1,6 @@ import pickle -from PyQt5.QtCore import Qt, pyqtSignal +from PyQt5.QtCore import Qt, pyqtSignal, QPoint from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import (QFileDialog, QHBoxLayout, QMdiSubWindow, QMenu, QPushButton, QSizePolicy, @@ -45,8 +45,8 @@ class fileWindow(QMdiSubWindow): self.setWindowTitle(title) #This is done so that a right click menu is shown on right click - self.setContextMenuPolicy(Qt.CustomContextMenu) - self.customContextMenuRequested.connect(self.contextMenu) + self.tabber.setContextMenuPolicy(Qt.CustomContextMenu) + self.tabber.customContextMenuRequested.connect(self.contextMenu) # self.setAttribute(Qt.WA_DeleteOnClose, True) self.setWindowFlag(Qt.CustomizeWindowHint, True) @@ -79,6 +79,8 @@ class fileWindow(QMdiSubWindow): 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) def resizeHandler(self): # resize Handler to handle resize cases. @@ -110,7 +112,8 @@ class fileWindow(QMdiSubWindow): menu.addAction("Adjust Canvas", self.adjustCanvasDialog) menu.addAction("Remove Side View" if self.sideViewTab == self.tabber.currentWidget() else "View Side-By-Side", self.sideViewMode) - menu.exec_(self.mapToGlobal(point)) + menu.addAction("Reset Zoom", lambda : setattr(self.tabber.currentWidget().view, 'zoom', 1)) + menu.exec_(self.tabber.mapToGlobal(point)) def sideViewMode(self): #helper context menu function to toggle side view @@ -147,7 +150,21 @@ class fileWindow(QMdiSubWindow): # x -= self.style().pixelMetric(QStyle.PM_ScrollBarExtent) # self.sideViewCloseButton.move(x, 5) self.sideViewCloseButton.move(5, 5) - + + def sideViewContextMenu(self, point): + menu = QMenu("Context Menu", self.sideView) + menu.addAction("Close Side View", lambda : setattr(self, 'sideViewTab', None)) + menu.addAction("Switch side view tab", self.sideViewSwitchTab) + menu.addAction("Reset Zoom", lambda : setattr(self.sideView, 'zoom', 1)) + menu.exec_(self.sideView.mapToGlobal(point)) + + def sideViewSwitchTab(self): + tabList = [f'{i}. {j.objectName()}' for i, j in enumerate(self.tabList)] + ['None (Remove)'] + initial = self.tabList.index(self.sideViewTab) + result = dialogs.sideViewSwitchDialog(self.tabber, tabList, initial).exec_() + if result != initial: + self.sideViewTab = self.tabber.widget(result) if result 5: + menu.addAction("Show switch menu", self.sideViewSwitchTab) + else: + for i in range(self.tabCount): + j = self.tabber.widget(i) + if j == self.sideViewTab: + continue + menu.addAction(f'{i}. {j.objectName()}', lambda index=i: self.sideViewSwitchCMenu(index)) + menu.addAction("Remove side view", lambda : setattr(self, 'sideViewTab', None)) menu.exec_(self.sideView.mapToGlobal(point)) + def sideViewSwitchCMenu(self, index): + print(index) + self.sideViewTab = self.tabber.widget(index) + def sideViewSwitchTab(self): - tabList = [f'{i}. {j.objectName()}' for i, j in enumerate(self.tabList)] + ['None (Remove)'] + tabList = [f'{i}. {j.objectName()}' for i, j in enumerate(self.tabList)] initial = self.tabList.index(self.sideViewTab) result = dialogs.sideViewSwitchDialog(self.tabber, tabList, initial).exec_() if result != initial: -- cgit From c70c63d437bca2bb6fbc428281a6aac4f3a28bd8 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 9 May 2020 14:40:23 +0530 Subject: Week 3 update --- src/main/python/utils/dialogs.py | 27 +++++++++++---------------- src/main/python/utils/fileWindow.py | 20 +++++++++++--------- src/main/python/utils/graphics.py | 21 ++++++++++++++------- 3 files changed, 36 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/dialogs.py b/src/main/python/utils/dialogs.py index 8ab8f6f..4351f16 100644 --- a/src/main/python/utils/dialogs.py +++ b/src/main/python/utils/dialogs.py @@ -10,8 +10,8 @@ class paperDims(QDialog): super(paperDims, self).__init__(parent) #store initial values to show currently set value, also updated when changed. these are returned at EOL - self._canvasSize = size - self._ppi = ppi + self.returnCanvasSize = size + self.returnCanvasPPI = ppi self.setWindowTitle(name+" :Canvas Size") #Set Window Title #init layout @@ -20,19 +20,19 @@ class paperDims(QDialog): sizeComboBox = QComboBox() #combo box for paper sizes sizeComboBox.addItems(sheetDimensionList) sizeComboBox.setCurrentIndex(4) - sizeComboBox.activated[str].connect(self.setCanvasSize) + sizeComboBox.activated[str].connect(lambda size: setattr(self, "returnCanvasSize", size)) sizeLabel = QLabel("Canvas Size") sizeLabel.setBuddy(sizeComboBox) # label for the above combo box - sizeComboBox.setCurrentIndex(sheetDimensionList.index(self._canvasSize)) #set index to current value of canvas + sizeComboBox.setCurrentIndex(sheetDimensionList.index(self.returnCanvasSize)) #set index to current value of canvas dialogBoxLayout.setWidget(0, QFormLayout.LabelRole, sizeLabel) dialogBoxLayout.setWidget(0, QFormLayout.FieldRole, sizeComboBox) ppiComboBox = QComboBox() #combo box for ppis ppiComboBox.addItems(ppiList) - ppiComboBox.activated[str].connect(self.setCanvasPPI) + ppiComboBox.activated[str].connect(lambda ppi: setattr(self, "returnCanvasPPI", ppi)) ppiLabel = QLabel("Canvas ppi") ppiLabel.setBuddy(ppiComboBox) # label for the above combo box - ppiComboBox.setCurrentIndex(ppiList.index(self._ppi)) #set index to current value of canvas + ppiComboBox.setCurrentIndex(ppiList.index(self.returnCanvasPPI)) #set index to current value of canvas dialogBoxLayout.setWidget(1, QFormLayout.LabelRole, ppiLabel) dialogBoxLayout.setWidget(1, QFormLayout.FieldRole, ppiComboBox) @@ -44,24 +44,19 @@ class paperDims(QDialog): dialogBoxLayout.addWidget(buttonBox) self.setLayout(dialogBoxLayout) self.resize(300,100) #resize to a certain size - - def setCanvasSize(self, size): - #for standard combo box behaviour - self._canvasSize = size - - def setCanvasPPI(self, ppi): - #for standard combo box behaviour - self._ppi = ppi def exec_(self): #overload exec_ to add return values and delete itself(currently being tested) super(paperDims, self).exec_() self.deleteLater() #remove from memory #if ok was pressed return value else return None - return (self._canvasSize, self._ppi) if self.result() else None + return (self.returnCanvasSize, self.returnCanvasPPI) if self.result() else None class sideViewSwitchDialog(QDialog): - + """ + Custom dialog box to show, all available tabs to set the side view to. + Also has accept reject events. Structure is similar to paperDims dialog box. + """ def __init__(self, parent=None, tabList = None, initial = None): super(sideViewSwitchDialog, self).__init__(parent=parent) self.tabList = tabList diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index 0230cd2..e549568 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -145,35 +145,37 @@ class fileWindow(QMdiSubWindow): return False def moveSideViewCloseButton(self): - # x = self.rect().width()//2 - 5 - # if self.sideView.verticalScrollBar().isVisible(): - # x -= self.style().pixelMetric(QStyle.PM_ScrollBarExtent) - # self.sideViewCloseButton.move(x, 5) + # used to place side view close button at appropriate position self.sideViewCloseButton.move(5, 5) def sideViewContextMenu(self, point): + # context menu for side view menu = QMenu("Context Menu", self.sideView) menu.addAction("Reset Zoom", lambda : setattr(self.sideView, 'zoom', 1)) menu.addSection('Change Side View Tab') if self.tabCount > 5: + # just show switch dialog box, if there are 6 or more tabs open menu.addAction("Show switch menu", self.sideViewSwitchTab) else: + # enumerate all tabs from side view. for i in range(self.tabCount): j = self.tabber.widget(i) - if j == self.sideViewTab: + if j == self.sideViewTab: continue + # evaluate i as index, weird lambda behaviour + #see https://stackoverflow.com/a/33984811/7799568 menu.addAction(f'{i}. {j.objectName()}', lambda index=i: self.sideViewSwitchCMenu(index)) menu.addAction("Remove side view", lambda : setattr(self, 'sideViewTab', None)) menu.exec_(self.sideView.mapToGlobal(point)) def sideViewSwitchCMenu(self, index): - print(index) self.sideViewTab = self.tabber.widget(index) def sideViewSwitchTab(self): - tabList = [f'{i}. {j.objectName()}' for i, j in enumerate(self.tabList)] - initial = self.tabList.index(self.sideViewTab) - result = dialogs.sideViewSwitchDialog(self.tabber, tabList, initial).exec_() + # displays a side view switch dialog box + tabList = [f'{i}. {j.objectName()}' for i, j in enumerate(self.tabList)] #names and index of all tabs + initial = self.tabList.index(self.sideViewTab) # current side view tab + result = dialogs.sideViewSwitchDialog(self.tabber, tabList, initial).exec_() #call dialog box if result != initial: self.sideViewTab = self.tabber.widget(result) if result 0.1: + #overload wheelevent, to zoom if control is pressed, else scroll normally + if Qt.ControlModifier: #check if control is pressed + if QWheelEvent.source() == Qt.MouseEventNotSynthesized: #check if precision mouse(mac) + # angle delta is 1/8th of a degree per scroll unit + if self.zoom + QWheelEvent.angleDelta().y()/2880 > 0.1: # hit and trial value (2880) self.zoom += QWheelEvent.angleDelta().y()/2880 else: + # precision delta is exactly equal to amount to scroll if self.zoom + QWheelEvent.pixelDelta().y() > 0.1: self.zoom += QWheelEvent.angleDelta().y() - QWheelEvent.accept() + QWheelEvent.accept() # accept event so that scrolling doesnt happen simultaneously else: - return super().wheelEvent(self, QWheelEvent) + return super().wheelEvent(self, QWheelEvent) # scroll if ctrl not pressed @property def zoom(self): + # property for zoom return self._zoom @zoom.setter def zoom(self, value): + # set scale according to zoom value being set temp = self.zoom self._zoom = value self.scale(self.zoom / temp, self.zoom / temp) \ No newline at end of file -- cgit From 27bc65463dd9867c5d8c011639b7958bd7824518 Mon Sep 17 00:00:00 2001 From: Blaine Date: Mon, 11 May 2020 19:44:11 +0530 Subject: refactoring and toolbar --- src/main/icons/toolbar/ellipse.png | Bin 0 -> 37162 bytes src/main/python/main.py | 28 ++++++++++++------ src/main/python/utils/canvas.py | 2 +- src/main/python/utils/data.py | 47 ++++++++++++++++++++++++++++++ src/main/python/utils/dialogs.py | 2 +- src/main/python/utils/funcs.py | 4 +++ src/main/python/utils/sizes.py | 36 ----------------------- src/main/python/utils/toolbar.py | 58 +++++++++++++++++++++++++++++++++++++ 8 files changed, 130 insertions(+), 47 deletions(-) create mode 100644 src/main/icons/toolbar/ellipse.png create mode 100644 src/main/python/utils/data.py create mode 100644 src/main/python/utils/funcs.py delete mode 100644 src/main/python/utils/sizes.py create mode 100644 src/main/python/utils/toolbar.py (limited to 'src') diff --git a/src/main/icons/toolbar/ellipse.png b/src/main/icons/toolbar/ellipse.png new file mode 100644 index 0000000..e708bdd Binary files /dev/null and b/src/main/icons/toolbar/ellipse.png differ diff --git a/src/main/python/main.py b/src/main/python/main.py index fc4c145..583baf0 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -3,15 +3,17 @@ import sys from fbs_runtime.application_context.PyQt5 import ApplicationContext from PyQt5.QtCore import QObject, Qt, pyqtSignal -from PyQt5.QtGui import QBrush, QColor, QImage, QPainter, QPalette +from PyQt5.QtGui import QBrush, QColor, QImage, QPainter, QPalette, QPen from PyQt5.QtWidgets import (QComboBox, QFileDialog, QFormLayout, QVBoxLayout, QHBoxLayout, QLabel, QMainWindow, QMenu, - QPushButton, QWidget, QMdiArea, QSplitter) + QPushButton, QWidget, QMdiArea, QSplitter, QGraphicsItem) +from PyQt5 import QtWidgets from utils.canvas import canvas from utils.fileWindow import fileWindow -from utils.sizes import ppiList, sheetDimensionList +from utils.data import ppiList, sheetDimensionList from utils import dialogs +from utils.toolbar import toolbar class appWindow(QMainWindow): """ @@ -44,7 +46,7 @@ class appWindow(QMainWindow): #create toolbar and add the toolbar plus mdi to layout self.createToolbar() - mainLayout.addWidget(self.toolbar) + # mainLayout.addWidget(self.toolbar) mainLayout.addWidget(QSplitter(Qt.Vertical, self)) mainLayout.addWidget(self.mdi) @@ -62,11 +64,19 @@ class appWindow(QMainWindow): def createToolbar(self): #place holder for toolbar with fixed width, layout may change - self.toolbar = QWidget(self.mainWidget) - self.toolbar.setObjectName("Toolbar") - self.toolbar.setFixedWidth(200) - toolbarLayout = QFormLayout(self.toolbar) - self.toolbar.setLayout(toolbarLayout) + self.toolbar = toolbar(self.mainWidget) + # self.toolbar.setObjectName("Toolbar") + self.addToolBar(Qt.LeftToolBarArea, self.toolbar) + self.toolbar.toolbuttonClicked.connect(self.toolButtonClicked) + self.toolbar.populateToolbar() + + def toolButtonClicked(self, object): + currentDiagram = self.mdi.currentSubWindow().tabber.currentWidget().painter + if currentDiagram: + graphic = getattr(QtWidgets, object['object'])(*object['args']) + graphic.setPen(QPen(Qt.black, 2)) + graphic.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable) + currentDiagram.addItem(graphic) def newProject(self): #call to create a new file inside mdi area diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index a4c56f3..d393e36 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -8,7 +8,7 @@ from PyQt5.QtWidgets import (QFileDialog, QApplication, from . import dialogs from .graphics import customView -from .sizes import paperSizes, ppiList, sheetDimensionList +from .data import paperSizes, ppiList, sheetDimensionList class canvas(QWidget): """ diff --git a/src/main/python/utils/data.py b/src/main/python/utils/data.py new file mode 100644 index 0000000..d0b5ca1 --- /dev/null +++ b/src/main/python/utils/data.py @@ -0,0 +1,47 @@ +paperSizes = { + "A0": { + "72": [2384, 3370], + "96": [3179, 4494], + "150": [4967, 7022], + "300": [9933, 14043] + }, + "A1": { + "72": [1684, 2384], + "96": [2245, 3179], + "150": [3508, 4967], + "300": [7016, 9933] + }, + "A2": { + "72": [1191, 1684], + "96": [1587, 2245], + "150": [2480, 3508], + "300": [4960, 7016] + }, + "A3": { + "72": [842, 1191], + "96": [1123, 1587], + "150": [1754, 2480], + "300": [3508, 4960] + }, + "A4": { + "72": [595, 842], + "96": [794, 1123], + "150": [1240, 1754], + "300": [2480, 3508] + } +} + +sheetDimensionList = [f'A{i}' for i in range(5)] + +ppiList = ["72", "96", "150", "300"] + +toolbarItems = { + 'Ellipse': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + } +} + +defaultToolbarItems = toolbarItems.keys() \ No newline at end of file diff --git a/src/main/python/utils/dialogs.py b/src/main/python/utils/dialogs.py index 4351f16..e008aa5 100644 --- a/src/main/python/utils/dialogs.py +++ b/src/main/python/utils/dialogs.py @@ -1,5 +1,5 @@ from PyQt5.QtWidgets import QDialog, QPushButton, QFormLayout, QComboBox, QLabel, QMessageBox, QDialogButtonBox -from .sizes import sheetDimensionList, ppiList +from .data import sheetDimensionList, ppiList class paperDims(QDialog): """ diff --git a/src/main/python/utils/funcs.py b/src/main/python/utils/funcs.py new file mode 100644 index 0000000..cd2dc65 --- /dev/null +++ b/src/main/python/utils/funcs.py @@ -0,0 +1,4 @@ +from itertools import zip_longest +def grouper(n, iterable, fillvalue=None): + args = [iter(iterable)] * n + return zip_longest(fillvalue=fillvalue, *args) \ No newline at end of file diff --git a/src/main/python/utils/sizes.py b/src/main/python/utils/sizes.py deleted file mode 100644 index b0aa70a..0000000 --- a/src/main/python/utils/sizes.py +++ /dev/null @@ -1,36 +0,0 @@ -paperSizes = { - "A0": { - "72": [2384, 3370], - "96": [3179, 4494], - "150": [4967, 7022], - "300": [9933, 14043] - }, - "A1": { - "72": [1684, 2384], - "96": [2245, 3179], - "150": [3508, 4967], - "300": [7016, 9933] - }, - "A2": { - "72": [1191, 1684], - "96": [1587, 2245], - "150": [2480, 3508], - "300": [4960, 7016] - }, - "A3": { - "72": [842, 1191], - "96": [1123, 1587], - "150": [1754, 2480], - "300": [3508, 4960] - }, - "A4": { - "72": [595, 842], - "96": [794, 1123], - "150": [1240, 1754], - "300": [2480, 3508] - } -} - -sheetDimensionList = [f'A{i}' for i in range(5)] - -ppiList = ["72", "96", "150", "300"] \ No newline at end of file diff --git a/src/main/python/utils/toolbar.py b/src/main/python/utils/toolbar.py new file mode 100644 index 0000000..9a48aa9 --- /dev/null +++ b/src/main/python/utils/toolbar.py @@ -0,0 +1,58 @@ +from PyQt5.QtCore import pyqtSignal, QSize +from PyQt5.QtGui import QIcon +from PyQt5.QtWidgets import QToolBar, QWidget, QHBoxLayout, QLineEdit, QToolButton + +from .data import defaultToolbarItems, toolbarItems +from .funcs import grouper + +class toolbar(QToolBar): + toolbuttonClicked = pyqtSignal(dict) + + def __init__(self, parent = None): + super(toolbar, self).__init__(parent) + self.toolbarItems = defaultToolbarItems + self.toolbarWidgets = [] + self.setFixedWidth = 200 + + self.searchBox = QLineEdit(self) + self.searchBox.textChanged.connect(self.searchQuery) + self.addWidget(self.searchBox) + + def populateToolbar(self): + # self.clearWidgets() + + for a, b, c in grouper(3, self.toolbarItems): + widget = QWidget(self) + layout = QHBoxLayout(widget) + if a is not None: + item = toolbarItems[a] + button = toolbarButton(self, item) + button.clicked.connect(lambda : self.toolbuttonClicked.emit(item)) + layout.addWidget(button) + # layout.addItem(b) + # layout.addItem(c) + self.toolbarWidgets.append(widget) + self.addWidget(widget) + + def clearWidgets(self): + for i in self.toolbarWidgets(): + i.deleteLater() + + def searchQuery(self): + # shorten toolbaritems list with search items + # self.populateToolbar() # populate with toolbar items + text = self.searchBox.toPlainText() + if text == '': + self.toolbarItems = defaultToolbarItems + else: + pass + #implement shortlisting + +class toolbarButton(QToolButton): + + def __init__(self, parent = None, item = None): + super(toolbarButton, self).__init__(parent) + self.setIcon(QIcon(f'../../icons/toolbar/{item["icon"]}')) + self.setIconSize(QSize(25, 25)) + self.setText(f'item["name"]') + self.setFixedSize(30, 30) \ No newline at end of file -- cgit From b228d617e0344bc3922a29ebaf742d855eb91266 Mon Sep 17 00:00:00 2001 From: Blaine Date: Tue, 12 May 2020 20:08:10 +0530 Subject: toolbar sectioning --- src/main/icons/toolbar/ellipse.png | Bin 37162 -> 0 bytes src/main/python/main.py | 11 +- src/main/python/utils/data.py | 266 +++++++++++++++++++++++++++- src/main/python/utils/funcs.py | 1 + src/main/python/utils/layout.py | 88 +++++++++ src/main/python/utils/toolbar.py | 77 +++++--- src/main/resources/base/toolbar/ellipse.png | Bin 0 -> 37162 bytes 7 files changed, 412 insertions(+), 31 deletions(-) delete mode 100644 src/main/icons/toolbar/ellipse.png create mode 100644 src/main/python/utils/layout.py create mode 100644 src/main/resources/base/toolbar/ellipse.png (limited to 'src') diff --git a/src/main/icons/toolbar/ellipse.png b/src/main/icons/toolbar/ellipse.png deleted file mode 100644 index e708bdd..0000000 Binary files a/src/main/icons/toolbar/ellipse.png and /dev/null differ diff --git a/src/main/python/main.py b/src/main/python/main.py index 583baf0..b54f931 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -65,11 +65,13 @@ class appWindow(QMainWindow): def createToolbar(self): #place holder for toolbar with fixed width, layout may change self.toolbar = toolbar(self.mainWidget) - # self.toolbar.setObjectName("Toolbar") - self.addToolBar(Qt.LeftToolBarArea, self.toolbar) + self.toolbar.setObjectName("Toolbar") + self.addToolBar(Qt.LeftToolBarArea, self.toolbar) + # self.addDockWidget(Qt.LeftDockWidgetArea, self.toolbar) self.toolbar.toolbuttonClicked.connect(self.toolButtonClicked) self.toolbar.populateToolbar() + def toolButtonClicked(self, object): currentDiagram = self.mdi.currentSubWindow().tabber.currentWidget().painter if currentDiagram: @@ -133,6 +135,7 @@ class appWindow(QMainWindow): #overload resize to also handle resize on file windows inside for i in self.mdi.subWindowList(): i.resizeHandler() + # self.toolbar.resize() super(appWindow, self).resizeEvent(event) def closeEvent(self, event): @@ -194,7 +197,7 @@ class appWindow(QMainWindow): if __name__ == '__main__': app = ApplicationContext() # 1. Instantiate ApplicationContext - test = appWindow() - test.show() + main = appWindow() + main.show() exit_code = app.app.exec_() # 2. Invoke appctxt.app.exec_() sys.exit(exit_code) diff --git a/src/main/python/utils/data.py b/src/main/python/utils/data.py index d0b5ca1..593cb1b 100644 --- a/src/main/python/utils/data.py +++ b/src/main/python/utils/data.py @@ -41,7 +41,271 @@ toolbarItems = { 'icon': 'ellipse.png', 'object': 'QGraphicsEllipseItem', 'args': [20, 20, 300, 300] - } + }, + 'Ellipse2': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse3': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse4': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse5': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse6': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse7': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse8': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse9': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse11': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse12': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse13': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse14': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse15': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse16': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse17': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse18': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse19': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse20': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse21': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse22': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse23': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse24': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse25': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse26': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse27': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse28': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse29': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse30': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse31': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse32': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse33': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse34': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse35': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse36': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse37': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse38': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse39': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse40': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse41': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse42': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse43': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse44': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse45': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, + 'Ellipse46': { + 'name': 'Ellipse', + 'icon': 'ellipse.png', + 'object': 'QGraphicsEllipseItem', + 'args': [20, 20, 300, 300] + }, } defaultToolbarItems = toolbarItems.keys() \ No newline at end of file diff --git a/src/main/python/utils/funcs.py b/src/main/python/utils/funcs.py index cd2dc65..7796ece 100644 --- a/src/main/python/utils/funcs.py +++ b/src/main/python/utils/funcs.py @@ -1,4 +1,5 @@ from itertools import zip_longest + def grouper(n, iterable, fillvalue=None): args = [iter(iterable)] * n return zip_longest(fillvalue=fillvalue, *args) \ No newline at end of file diff --git a/src/main/python/utils/layout.py b/src/main/python/utils/layout.py new file mode 100644 index 0000000..1aa59ac --- /dev/null +++ b/src/main/python/utils/layout.py @@ -0,0 +1,88 @@ +from PyQt5.QtCore import Qt, QRect, QPoint, QSize +from PyQt5.QtWidgets import QLayout, QSizePolicy + +class flowLayout(QLayout): + def __init__(self, parent=None, margin=0, spacing=-1): + super(flowLayout, self).__init__(parent) + + if parent is not None: + self.setContentsMargins(margin, margin, margin, margin) + + self.setSpacing(spacing) + + self.itemList = [] + + def __del__(self): + item = self.takeAt(0) + while item: + item = self.takeAt(0) + + def addItem(self, item): + self.itemList.append(item) + + def count(self): + return len(self.itemList) + + def itemAt(self, index): + if index >= 0 and index < len(self.itemList): + return self.itemList[index] + + return None + + def takeAt(self, index): + if index >= 0 and index < len(self.itemList): + return self.itemList.pop(index) + + return None + + def expandingDirections(self): + return Qt.Orientations(Qt.Orientation(0)) + + def hasHeightForWidth(self): + return True + + def heightForWidth(self, width): + height = self.doLayout(QRect(0, 0, width, 0), True) + return height + + def setGeometry(self, rect): + super(flowLayout, self).setGeometry(rect) + self.doLayout(rect, False) + + def sizeHint(self): + return self.minimumSize() + + def minimumSize(self): + size = QSize() + + for item in self.itemList: + size = size.expandedTo(item.minimumSize()) + + margin, _, _, _ = self.getContentsMargins() + + size += QSize(2 * margin, 2 * margin) + return size + + def doLayout(self, rect, testOnly): + x = rect.x() + y = rect.y() + lineHeight = 0 + + for item in self.itemList: + wid = item.widget() + spaceX = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Horizontal) + spaceY = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Vertical) + nextX = x + item.sizeHint().width() + spaceX + if nextX - spaceX > rect.right() and lineHeight > 0: + x = rect.x() + y = y + lineHeight + spaceY + nextX = x + item.sizeHint().width() + spaceX + lineHeight = 0 + + if not testOnly: + item.setGeometry(QRect(QPoint(x, y), item.sizeHint())) + + x = nextX + lineHeight = max(lineHeight, item.sizeHint().height()) + + return y + lineHeight - rect.y() diff --git a/src/main/python/utils/toolbar.py b/src/main/python/utils/toolbar.py index 9a48aa9..68e8865 100644 --- a/src/main/python/utils/toolbar.py +++ b/src/main/python/utils/toolbar.py @@ -1,9 +1,14 @@ -from PyQt5.QtCore import pyqtSignal, QSize +from fbs_runtime.application_context.PyQt5 import ApplicationContext + +from PyQt5.QtCore import pyqtSignal, QSize, Qt from PyQt5.QtGui import QIcon -from PyQt5.QtWidgets import QToolBar, QWidget, QHBoxLayout, QLineEdit, QToolButton +from PyQt5.QtWidgets import QToolBar, QWidget, QGridLayout, QLineEdit, QToolButton, QScrollArea, QDockWidget, QVBoxLayout from .data import defaultToolbarItems, toolbarItems from .funcs import grouper +from .layout import flowLayout + +resourceManager = ApplicationContext() class toolbar(QToolBar): toolbuttonClicked = pyqtSignal(dict) @@ -11,32 +16,41 @@ class toolbar(QToolBar): def __init__(self, parent = None): super(toolbar, self).__init__(parent) self.toolbarItems = defaultToolbarItems - self.toolbarWidgets = [] - self.setFixedWidth = 200 + # self.widget = QWidget(self) + # self.layout = QVBoxLayout(self.widget) + self.setAllowedAreas(Qt.LeftToolBarArea | Qt.RightToolBarArea) self.searchBox = QLineEdit(self) + # self.searchBox = QLineEdit(self.widget) self.searchBox.textChanged.connect(self.searchQuery) self.addWidget(self.searchBox) + # self.layout.addWidget(self.searchBox) + + self.addSeparator() + self.diagArea = QScrollArea(self) + self.addWidget(self.diagArea) + # self.layout.addWidget(self.diagArea) + self.diagAreaWidget = QWidget() + self.diagAreaWidget.setFixedWidth(200) + # self.setWidget(self.widget) def populateToolbar(self): - # self.clearWidgets() - - for a, b, c in grouper(3, self.toolbarItems): - widget = QWidget(self) - layout = QHBoxLayout(widget) - if a is not None: - item = toolbarItems[a] - button = toolbarButton(self, item) - button.clicked.connect(lambda : self.toolbuttonClicked.emit(item)) - layout.addWidget(button) - # layout.addItem(b) - # layout.addItem(c) - self.toolbarWidgets.append(widget) - self.addWidget(widget) - - def clearWidgets(self): - for i in self.toolbarWidgets(): - i.deleteLater() + # layout = QGridLayout(self.diagAreaWidget) + # n = self.width() // 45 + # for i, items in enumerate(grouper(n, self.toolbarItems)): + # for j, item in enumerate(items): + # if item is not None: + # item = toolbarItems[item] + # button = toolbarButton(self, item) + # button.clicked.connect(lambda : self.toolbuttonClicked.emit(item)) + # layout.addWidget(button, i, j, 1, 1, alignment=Qt.AlignHCenter) + layout = flowLayout(self.diagAreaWidget) + for item in self.toolbarItems: + obj = toolbarItems[item] + button = toolbarButton(self, obj) + button.clicked.connect(lambda : self.toolbuttonClicked.emit(obj)) + layout.addWidget(button) + self.diagArea.setWidget(self.diagAreaWidget) def searchQuery(self): # shorten toolbaritems list with search items @@ -47,12 +61,23 @@ class toolbar(QToolBar): else: pass #implement shortlisting - + + def resize(self): + pass + + def resizeEvent(self, event): + self.resize() + self.setFixedWidth(.11*self.parentWidget().width()) + self.diagAreaWidget.setFixedWidth(.11*self.parentWidget().width() - 30) + self.diagArea.setFixedHeight(.7*self.parentWidget().height()) + return super(toolbar, self).resizeEvent(event) + class toolbarButton(QToolButton): def __init__(self, parent = None, item = None): super(toolbarButton, self).__init__(parent) - self.setIcon(QIcon(f'../../icons/toolbar/{item["icon"]}')) - self.setIconSize(QSize(25, 25)) + self.setIcon(QIcon(resourceManager.get_resource(f'toolbar/{item["icon"]}'))) + self.setIconSize(QSize(40, 40)) self.setText(f'item["name"]') - self.setFixedSize(30, 30) \ No newline at end of file + self.setFixedSize(30, 30) + \ No newline at end of file diff --git a/src/main/resources/base/toolbar/ellipse.png b/src/main/resources/base/toolbar/ellipse.png new file mode 100644 index 0000000..e708bdd Binary files /dev/null and b/src/main/resources/base/toolbar/ellipse.png differ -- cgit From 055276d6ec4ffa7d812df6d5b2811eb87d685444 Mon Sep 17 00:00:00 2001 From: Blaine Date: Wed, 13 May 2020 18:20:54 +0530 Subject: fixed toolbar issues --- src/main/python/main.py | 25 ++++----- src/main/python/utils/layout.py | 7 ++- src/main/python/utils/toolbar.py | 113 ++++++++++++++++++++++++--------------- 3 files changed, 82 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index b54f931..54e0711 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -22,11 +22,10 @@ class appWindow(QMainWindow): """ def __init__(self, parent=None): super(appWindow, self).__init__(parent) - self.mainWidget = QWidget(self) #create new widget #create the menu bar titleMenu = self.menuBar() #fetch reference to current menu bar - self.mainWidget.setObjectName("Main Widget") + # self.mainWidget.setObjectName("Main Widget") self.menuFile = titleMenu.addMenu('File') #File Menu self.menuFile.addAction("New", self.newProject) @@ -36,19 +35,12 @@ class appWindow(QMainWindow): self.menuGenerate = titleMenu.addMenu('Generate') #Generate menu self.menuGenerate.addAction("Image", self.saveImage) self.menuGenerate.addAction("Report", self.generateReport) - - # create new layout for the main widget - mainLayout = QHBoxLayout() - mainLayout.setObjectName("Main Layout") 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() - # mainLayout.addWidget(self.toolbar) - mainLayout.addWidget(QSplitter(Qt.Vertical, self)) - mainLayout.addWidget(self.mdi) #set flags so that window doesnt look weird self.mdi.setOption(QMdiArea.DontMaximizeSubWindowOnActivation, True) @@ -57,19 +49,20 @@ class appWindow(QMainWindow): self.mdi.setDocumentMode(False) #declare main window layout - self.mainWidget.setLayout(mainLayout) - self.setCentralWidget(self.mainWidget) + # self.mainWidget.setLayout(mainLayout) + self.setCentralWidget(self.mdi) self.resize(1280, 720) #set collapse dim self.mdi.subWindowActivated.connect(self.tabSwitched) + def createToolbar(self): #place holder for toolbar with fixed width, layout may change - self.toolbar = toolbar(self.mainWidget) + self.toolbar = toolbar(self) self.toolbar.setObjectName("Toolbar") - self.addToolBar(Qt.LeftToolBarArea, self.toolbar) - # self.addDockWidget(Qt.LeftDockWidgetArea, self.toolbar) + # self.addToolBar(Qt.LeftToolBarArea, self.toolbar) + self.addDockWidget(Qt.LeftDockWidgetArea, self.toolbar) self.toolbar.toolbuttonClicked.connect(self.toolButtonClicked) - self.toolbar.populateToolbar() + self.toolbar.populateToolbar(self.toolbar.toolbarItemList) def toolButtonClicked(self, object): @@ -135,7 +128,7 @@ class appWindow(QMainWindow): #overload resize to also handle resize on file windows inside for i in self.mdi.subWindowList(): i.resizeHandler() - # self.toolbar.resize() + self.toolbar.resize() super(appWindow, self).resizeEvent(event) def closeEvent(self, event): diff --git a/src/main/python/utils/layout.py b/src/main/python/utils/layout.py index 1aa59ac..6781249 100644 --- a/src/main/python/utils/layout.py +++ b/src/main/python/utils/layout.py @@ -9,7 +9,6 @@ class flowLayout(QLayout): self.setContentsMargins(margin, margin, margin, margin) self.setSpacing(spacing) - self.itemList = [] def __del__(self): @@ -48,7 +47,7 @@ class flowLayout(QLayout): def setGeometry(self, rect): super(flowLayout, self).setGeometry(rect) self.doLayout(rect, False) - + def sizeHint(self): return self.minimumSize() @@ -70,8 +69,8 @@ class flowLayout(QLayout): for item in self.itemList: wid = item.widget() - spaceX = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Horizontal) - spaceY = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Vertical) + spaceX = self.spacing() + wid.style().layoutSpacing(QSizePolicy.ToolButton, QSizePolicy.ToolButton, Qt.Horizontal) + spaceY = self.spacing() + wid.style().layoutSpacing(QSizePolicy.ToolButton, QSizePolicy.ToolButton, Qt.Vertical) nextX = x + item.sizeHint().width() + spaceX if nextX - spaceX > rect.right() and lineHeight > 0: x = rect.x() diff --git a/src/main/python/utils/toolbar.py b/src/main/python/utils/toolbar.py index 68e8865..b870259 100644 --- a/src/main/python/utils/toolbar.py +++ b/src/main/python/utils/toolbar.py @@ -1,8 +1,8 @@ from fbs_runtime.application_context.PyQt5 import ApplicationContext - -from PyQt5.QtCore import pyqtSignal, QSize, Qt +from PyQt5.QtCore import QSize, Qt, pyqtSignal from PyQt5.QtGui import QIcon -from PyQt5.QtWidgets import QToolBar, QWidget, QGridLayout, QLineEdit, QToolButton, QScrollArea, QDockWidget, QVBoxLayout +from PyQt5.QtWidgets import (QBoxLayout, QDockWidget, QGridLayout, QLineEdit, + QScrollArea, QToolButton, QWidget) from .data import defaultToolbarItems, toolbarItems from .funcs import grouper @@ -10,68 +10,90 @@ from .layout import flowLayout resourceManager = ApplicationContext() -class toolbar(QToolBar): +class toolbar(QDockWidget): toolbuttonClicked = pyqtSignal(dict) def __init__(self, parent = None): super(toolbar, self).__init__(parent) - self.toolbarItems = defaultToolbarItems - # self.widget = QWidget(self) - # self.layout = QVBoxLayout(self.widget) - self.setAllowedAreas(Qt.LeftToolBarArea | Qt.RightToolBarArea) + self.toolbarButtonDict = dict() + self.toolbarItems(defaultToolbarItems) + self.diagAreaLayout = None + + self.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) + + self.widget = QWidget(self) + self.layout = QBoxLayout(QBoxLayout.TopToBottom, self.widget) + self.setAllowedAreas(Qt.AllDockWidgetAreas) + + self.searchBox = QLineEdit(self.widget) - self.searchBox = QLineEdit(self) - # self.searchBox = QLineEdit(self.widget) self.searchBox.textChanged.connect(self.searchQuery) - self.addWidget(self.searchBox) - # self.layout.addWidget(self.searchBox) + self.layout.addWidget(self.searchBox, alignment=Qt.AlignHCenter) - self.addSeparator() self.diagArea = QScrollArea(self) - self.addWidget(self.diagArea) - # self.layout.addWidget(self.diagArea) + self.layout.addWidget(self.diagArea) self.diagAreaWidget = QWidget() - self.diagAreaWidget.setFixedWidth(200) - # self.setWidget(self.widget) + + self.setWidget(self.widget) - def populateToolbar(self): - # layout = QGridLayout(self.diagAreaWidget) - # n = self.width() // 45 - # for i, items in enumerate(grouper(n, self.toolbarItems)): - # for j, item in enumerate(items): - # if item is not None: - # item = toolbarItems[item] - # button = toolbarButton(self, item) - # button.clicked.connect(lambda : self.toolbuttonClicked.emit(item)) - # layout.addWidget(button, i, j, 1, 1, alignment=Qt.AlignHCenter) - layout = flowLayout(self.diagAreaWidget) - for item in self.toolbarItems: - obj = toolbarItems[item] - button = toolbarButton(self, obj) - button.clicked.connect(lambda : self.toolbuttonClicked.emit(obj)) - layout.addWidget(button) + def populateToolbar(self, list): + if self.diagAreaLayout: + self.diagAreaLayout.deleteLater() + self.diagAreaLayout = flowLayout(self.diagAreaWidget) + for item in list: + self.diagAreaLayout.addWidget(self.toolbarButtonDict[item]) self.diagArea.setWidget(self.diagAreaWidget) def searchQuery(self): # shorten toolbaritems list with search items # self.populateToolbar() # populate with toolbar items - text = self.searchBox.toPlainText() + text = self.searchBox.text() if text == '': - self.toolbarItems = defaultToolbarItems + self.populateToolbar(self.toolbarItemList) else: pass #implement shortlisting - + def resize(self): - pass + parent = self.parentWidget() + # print(self.orientation()) + if parent.dockWidgetArea in [Qt.TopDockWidgetArea, Qt.BottomDockWidgetArea] and not self.isFloating(): + self.layout.setDirection(QBoxLayout.LeftToRight) + self.setFixedHeight(.12*parent.height()) + self.setFixedWidth(parent.width()) + self.diagAreaWidget.setFixedHeight(.12*parent.height() - 45) + else: + self.layout.setDirection(QBoxLayout.TopToBottom) + self.setFixedWidth(.12*parent.width()) + self.setFixedHeight(self.height()) + self.diagAreaWidget.setFixedWidth(.12*parent.width() - 45) def resizeEvent(self, event): - self.resize() - self.setFixedWidth(.11*self.parentWidget().width()) - self.diagAreaWidget.setFixedWidth(.11*self.parentWidget().width() - 30) - self.diagArea.setFixedHeight(.7*self.parentWidget().height()) + parent = self.parentWidget() + self.layout.setDirection(QBoxLayout.TopToBottom) + self.setFixedWidth(.12*parent.width()) + self.setFixedHeight(self.height()) + width = .12*parent.width() - 45 + self.diagAreaWidget.setFixedWidth(width) + self.diagAreaWidget.setFixedHeight(self.diagAreaLayout.heightForWidth(width)) return super(toolbar, self).resizeEvent(event) + # @property + # def toolbarItems(self): + # return self._toolbarItems + + # @toolbarItems.setter + def toolbarItems(self, items): + for item in items: + obj = toolbarItems[item] + button = toolbarButton(self, obj) + button.clicked.connect(lambda : self.toolbuttonClicked.emit(obj)) + self.toolbarButtonDict[item] = button + + @property + def toolbarItemList(self): + return self.toolbarButtonDict.keys() + class toolbarButton(QToolButton): def __init__(self, parent = None, item = None): @@ -79,5 +101,10 @@ class toolbarButton(QToolButton): self.setIcon(QIcon(resourceManager.get_resource(f'toolbar/{item["icon"]}'))) self.setIconSize(QSize(40, 40)) self.setText(f'item["name"]') - self.setFixedSize(30, 30) - \ No newline at end of file + # self.setFixedSize(30, 30) + + def sizeHint(self): + return self.minimumSizeHint() + + def minimumSizeHint(self): + return QSize(30, 30) \ No newline at end of file -- cgit From aab2924c33eaa4de26203aee76a8e1f4a8ee559d Mon Sep 17 00:00:00 2001 From: Blaine Date: Thu, 14 May 2020 20:56:49 +0530 Subject: enable drag and drop --- src/main/python/utils/canvas.py | 7 +++---- src/main/python/utils/graphics.py | 43 +++++++++++++++++++++++++++++++++++++-- src/main/python/utils/toolbar.py | 32 ++++++++++++++++++++++++----- 3 files changed, 71 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index d393e36..2332087 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -2,12 +2,11 @@ import pickle from PyQt5.QtCore import Qt from PyQt5.QtGui import QBrush, QPalette -from PyQt5.QtWidgets import (QFileDialog, QApplication, - QGraphicsScene, QGraphicsView, QHBoxLayout, QMenu, +from PyQt5.QtWidgets import (QFileDialog, QApplication, QHBoxLayout, QMenu, QTabWidget, QWidget, QSpacerItem, QStyle) from . import dialogs -from .graphics import customView +from .graphics import customView, customScene from .data import paperSizes, ppiList, sheetDimensionList class canvas(QWidget): @@ -28,7 +27,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 = QGraphicsScene() + 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 diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py index 4d754b5..243b086 100644 --- a/src/main/python/utils/graphics.py +++ b/src/main/python/utils/graphics.py @@ -1,5 +1,7 @@ from PyQt5.QtCore import Qt -from PyQt5.QtWidgets import QGraphicsView +from PyQt5.QtGui import QPen +from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsProxyWidget, QGraphicsItem +from PyQt5 import QtWidgets class customView(QGraphicsView): """ @@ -12,7 +14,24 @@ class customView(QGraphicsView): super(customView, self).__init__(parent) self._zoom = 1 self.setDragMode(True) + self.setAcceptDrops(True) + + def dragEnterEvent(self, QDragEnterEvent): + if QDragEnterEvent.mimeData().hasText(): + QDragEnterEvent.acceptProposedAction() + def dragMoveEvent(self, QDragMoveEvent): + if QDragMoveEvent.mimeData().hasText(): + QDragMoveEvent.acceptProposedAction() + + def dropEvent(self, QDropEvent): + if QDropEvent.mimeData().hasText(): + graphic = getattr(QtWidgets, QDropEvent.mimeData().text())(QDropEvent.pos().x(), QDropEvent.pos().y(), 300, 300) + graphic.setPen(QPen(Qt.black, 2)) + graphic.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable) + self.scene().addItem(graphic) + QDropEvent.acceptProposedAction() + def wheelEvent(self, QWheelEvent): #overload wheelevent, to zoom if control is pressed, else scroll normally if Qt.ControlModifier: #check if control is pressed @@ -38,4 +57,24 @@ class customView(QGraphicsView): # set scale according to zoom value being set temp = self.zoom self._zoom = value - self.scale(self.zoom / temp, self.zoom / temp) \ No newline at end of file + self.scale(self.zoom / temp, self.zoom / temp) + +class customScene(QGraphicsScene): + # def __init__(self, parent = None): + # super(customScene, self).__init__(parent) + def dragEnterEvent(self, e): + e.acceptProposedAction() + + def dropEvent(self, e): + # find item at these coordinates + item = self.itemAt(e.scenePos()) + if item.setAcceptDrops == True: + # pass on event to item at the coordinates + try: + item.dropEvent(e) + except RuntimeError: + pass #This will supress a Runtime Error generated when dropping into a widget with no MyProxy + + def dragMoveEvent(self, e): + e.acceptProposedAction() + \ No newline at end of file diff --git a/src/main/python/utils/toolbar.py b/src/main/python/utils/toolbar.py index b870259..1c0a492 100644 --- a/src/main/python/utils/toolbar.py +++ b/src/main/python/utils/toolbar.py @@ -1,8 +1,8 @@ from fbs_runtime.application_context.PyQt5 import ApplicationContext -from PyQt5.QtCore import QSize, Qt, pyqtSignal -from PyQt5.QtGui import QIcon +from PyQt5.QtCore import QSize, Qt, pyqtSignal, QMimeData +from PyQt5.QtGui import QIcon, QDrag from PyQt5.QtWidgets import (QBoxLayout, QDockWidget, QGridLayout, QLineEdit, - QScrollArea, QToolButton, QWidget) + QScrollArea, QToolButton, QWidget, QApplication) from .data import defaultToolbarItems, toolbarItems from .funcs import grouper @@ -100,9 +100,31 @@ class toolbarButton(QToolButton): super(toolbarButton, self).__init__(parent) self.setIcon(QIcon(resourceManager.get_resource(f'toolbar/{item["icon"]}'))) self.setIconSize(QSize(40, 40)) - self.setText(f'item["name"]') - # self.setFixedSize(30, 30) + self.dragStartPosition = 0 + self.itemObject = item['object'] + self.setText(item["name"]) + self.setToolTip(item["name"]) + def mousePressEvent(self, event): + if event.button() == Qt.LeftButton: + # if event.wasHeld: + self.dragStartPosition = event.pos() + # else: + # # super(toolbarButton, self).mousePressEvent(event) + # self.clicked.emit() + + def mouseMoveEvent(self, event): + if not (event.buttons() and Qt.LeftButton): + return + if (event.pos() - self.dragStartPosition).manhattanLength() < QApplication.startDragDistance(): + return + + drag = QDrag(self) + mimeData = QMimeData() + mimeData.setText(self.itemObject) + drag.setMimeData(mimeData) + drag.exec(Qt.CopyAction) + def sizeHint(self): return self.minimumSizeHint() -- cgit From e666d20c72138e1cb679b2877d90604c06130926 Mon Sep 17 00:00:00 2001 From: Blaine Date: Fri, 15 May 2020 11:56:00 +0530 Subject: working fix --- src/main/python/utils/graphics.py | 4 ++-- src/main/python/utils/toolbar.py | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py index 243b086..48d031b 100644 --- a/src/main/python/utils/graphics.py +++ b/src/main/python/utils/graphics.py @@ -25,8 +25,8 @@ class customView(QGraphicsView): QDragMoveEvent.acceptProposedAction() def dropEvent(self, QDropEvent): - if QDropEvent.mimeData().hasText(): - graphic = getattr(QtWidgets, QDropEvent.mimeData().text())(QDropEvent.pos().x(), QDropEvent.pos().y(), 300, 300) + if QDropEvent.mimeData().hasText(): + graphic = getattr(QtWidgets, QDropEvent.mimeData().text())(QDropEvent.pos().x()-150, QDropEvent.pos().y()-150, 300, 300) graphic.setPen(QPen(Qt.black, 2)) graphic.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable) self.scene().addItem(graphic) diff --git a/src/main/python/utils/toolbar.py b/src/main/python/utils/toolbar.py index 1c0a492..5abdbd4 100644 --- a/src/main/python/utils/toolbar.py +++ b/src/main/python/utils/toolbar.py @@ -106,12 +106,9 @@ class toolbarButton(QToolButton): self.setToolTip(item["name"]) def mousePressEvent(self, event): + super(toolbarButton, self).mousePressEvent(event) if event.button() == Qt.LeftButton: - # if event.wasHeld: self.dragStartPosition = event.pos() - # else: - # # super(toolbarButton, self).mousePressEvent(event) - # self.clicked.emit() def mouseMoveEvent(self, event): if not (event.buttons() and Qt.LeftButton): -- cgit From a7ac738d66a385ce1c5b89ca21cb5f69d4b8e801 Mon Sep 17 00:00:00 2001 From: Blaine Date: Fri, 15 May 2020 18:08:40 +0530 Subject: implement search box --- src/main/python/utils/toolbar.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/main/python/utils/toolbar.py b/src/main/python/utils/toolbar.py index 5abdbd4..93eb653 100644 --- a/src/main/python/utils/toolbar.py +++ b/src/main/python/utils/toolbar.py @@ -3,11 +3,13 @@ from PyQt5.QtCore import QSize, Qt, pyqtSignal, QMimeData from PyQt5.QtGui import QIcon, QDrag from PyQt5.QtWidgets import (QBoxLayout, QDockWidget, QGridLayout, QLineEdit, QScrollArea, QToolButton, QWidget, QApplication) +from re import search, IGNORECASE -from .data import defaultToolbarItems, toolbarItems +from .data import toolbarItems from .funcs import grouper from .layout import flowLayout + resourceManager = ApplicationContext() class toolbar(QDockWidget): @@ -16,8 +18,7 @@ class toolbar(QDockWidget): def __init__(self, parent = None): super(toolbar, self).__init__(parent) self.toolbarButtonDict = dict() - self.toolbarItems(defaultToolbarItems) - self.diagAreaLayout = None + self.toolbarItems(toolbarItems.keys()) self.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) @@ -33,13 +34,16 @@ class toolbar(QDockWidget): self.diagArea = QScrollArea(self) self.layout.addWidget(self.diagArea) self.diagAreaWidget = QWidget() + self.diagAreaLayout = flowLayout(self.diagAreaWidget) self.setWidget(self.widget) - + + def clearLayout(self): + for i in reversed(range(self.diagAreaLayout.count())): + self.diagAreaLayout.itemAt(i).widget().setParent(self) + def populateToolbar(self, list): - if self.diagAreaLayout: - self.diagAreaLayout.deleteLater() - self.diagAreaLayout = flowLayout(self.diagAreaWidget) + self.clearLayout() for item in list: self.diagAreaLayout.addWidget(self.toolbarButtonDict[item]) self.diagArea.setWidget(self.diagAreaWidget) @@ -51,12 +55,10 @@ class toolbar(QDockWidget): if text == '': self.populateToolbar(self.toolbarItemList) else: - pass - #implement shortlisting + self.populateToolbar(filter(lambda x: search(text, x, IGNORECASE), self.toolbarItemList)) def resize(self): parent = self.parentWidget() - # print(self.orientation()) if parent.dockWidgetArea in [Qt.TopDockWidgetArea, Qt.BottomDockWidgetArea] and not self.isFloating(): self.layout.setDirection(QBoxLayout.LeftToRight) self.setFixedHeight(.12*parent.height()) @@ -78,11 +80,6 @@ class toolbar(QDockWidget): self.diagAreaWidget.setFixedHeight(self.diagAreaLayout.heightForWidth(width)) return super(toolbar, self).resizeEvent(event) - # @property - # def toolbarItems(self): - # return self._toolbarItems - - # @toolbarItems.setter def toolbarItems(self, items): for item in items: obj = toolbarItems[item] -- cgit From c6a60b1c69daaa819ba52d29c5f5dc8a83023892 Mon Sep 17 00:00:00 2001 From: Blaine Date: Fri, 15 May 2020 18:14:17 +0530 Subject: minor cleanup --- src/main/python/main.py | 1 - src/main/python/utils/graphics.py | 2 -- 2 files changed, 3 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 54e0711..7d72bae 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -64,7 +64,6 @@ class appWindow(QMainWindow): self.toolbar.toolbuttonClicked.connect(self.toolButtonClicked) self.toolbar.populateToolbar(self.toolbar.toolbarItemList) - def toolButtonClicked(self, object): currentDiagram = self.mdi.currentSubWindow().tabber.currentWidget().painter if currentDiagram: diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py index 48d031b..6b2066f 100644 --- a/src/main/python/utils/graphics.py +++ b/src/main/python/utils/graphics.py @@ -60,8 +60,6 @@ class customView(QGraphicsView): self.scale(self.zoom / temp, self.zoom / temp) class customScene(QGraphicsScene): - # def __init__(self, parent = None): - # super(customScene, self).__init__(parent) def dragEnterEvent(self, e): e.acceptProposedAction() -- cgit From 7df3f6ab2aadbc178173a26a299c9a809aaa35f4 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 16 May 2020 11:55:23 +0530 Subject: QDragLeaveEvent + Generator functions --- src/main/python/main.py | 4 +++- src/main/python/utils/fileWindow.py | 3 ++- src/main/python/utils/graphics.py | 3 +++ src/main/python/utils/toolbar.py | 3 ++- 4 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index 7d72bae..ef52784 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -144,7 +144,9 @@ class appWindow(QMainWindow): @property def activeFiles(self): - return [i for i in self.mdi.subWindowList() if i.tabCount] + for i in self.mdi.subWindowList(): + if i.tabCount: + yield i @property def count(self): diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index e549568..4bd4ceb 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -187,7 +187,8 @@ class fileWindow(QMdiSubWindow): @property def tabList(self): #returns a list of tabs in the given window - return [self.tabber.widget(i) for i in range(self.tabCount)] + for i in range(self.tabCount): + yield self.tabber.widget(i) @property def tabCount(self): diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py index 6b2066f..dce664a 100644 --- a/src/main/python/utils/graphics.py +++ b/src/main/python/utils/graphics.py @@ -23,6 +23,9 @@ class customView(QGraphicsView): def dragMoveEvent(self, QDragMoveEvent): if QDragMoveEvent.mimeData().hasText(): QDragMoveEvent.acceptProposedAction() + + def dragLeaveEvent(self, QDragLeaveEvent): + QDragLeaveEvent.accept() def dropEvent(self, QDropEvent): if QDropEvent.mimeData().hasText(): diff --git a/src/main/python/utils/toolbar.py b/src/main/python/utils/toolbar.py index 93eb653..6f276df 100644 --- a/src/main/python/utils/toolbar.py +++ b/src/main/python/utils/toolbar.py @@ -89,7 +89,8 @@ class toolbar(QDockWidget): @property def toolbarItemList(self): - return self.toolbarButtonDict.keys() + for i in self.toolbarButtonDict.keys(): + yield i class toolbarButton(QToolButton): -- cgit From 051af95251fd0f87457322d9bd80ca99309c6c56 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 16 May 2020 18:24:07 +0530 Subject: minor clean up and comments --- src/main/python/main.py | 4 +- src/main/python/utils/fileWindow.py | 3 +- src/main/python/utils/graphics.py | 32 +++++------ src/main/python/utils/toolbar.py | 105 ++++++++++++++++++++---------------- 4 files changed, 74 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/main/python/main.py b/src/main/python/main.py index ef52784..7d72bae 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -144,9 +144,7 @@ class appWindow(QMainWindow): @property def activeFiles(self): - for i in self.mdi.subWindowList(): - if i.tabCount: - yield i + return [i for i in self.mdi.subWindowList() if i.tabCount] @property def count(self): diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index 4bd4ceb..e549568 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -187,8 +187,7 @@ class fileWindow(QMdiSubWindow): @property def tabList(self): #returns a list of tabs in the given window - for i in range(self.tabCount): - yield self.tabber.widget(i) + return [self.tabber.widget(i) for i in range(self.tabCount)] @property def tabCount(self): diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py index dce664a..0fe0030 100644 --- a/src/main/python/utils/graphics.py +++ b/src/main/python/utils/graphics.py @@ -5,7 +5,7 @@ from PyQt5 import QtWidgets class customView(QGraphicsView): """ - Defines custom QGraphicsView with zoom features, overriding wheel event + Defines custom QGraphicsView with zoom features and drag-drop accept event, overriding wheel event """ def __init__(self, scene = None, parent=None): if scene is not None: #overloaded constructor @@ -13,22 +13,28 @@ class customView(QGraphicsView): else: super(customView, self).__init__(parent) self._zoom = 1 - self.setDragMode(True) - self.setAcceptDrops(True) + self.setDragMode(True) #sets pannable using mouse + self.setAcceptDrops(True) #sets ability to accept drops + #following four functions are required to be overridden for drag-drop functionality def dragEnterEvent(self, QDragEnterEvent): + #defines acceptable drop items if QDragEnterEvent.mimeData().hasText(): QDragEnterEvent.acceptProposedAction() def dragMoveEvent(self, QDragMoveEvent): + #defines acceptable drop items if QDragMoveEvent.mimeData().hasText(): QDragMoveEvent.acceptProposedAction() def dragLeaveEvent(self, QDragLeaveEvent): + #accept any drag leave event, avoid unnecessary logging QDragLeaveEvent.accept() def dropEvent(self, QDropEvent): + #defines item drop, fetches text, creates corresponding QGraphicItem and adds it to scene if QDropEvent.mimeData().hasText(): + #QDropEvent.mimeData().text() defines intended drop item, the pos values define position graphic = getattr(QtWidgets, QDropEvent.mimeData().text())(QDropEvent.pos().x()-150, QDropEvent.pos().y()-150, 300, 300) graphic.setPen(QPen(Qt.black, 2)) graphic.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable) @@ -63,19 +69,9 @@ class customView(QGraphicsView): self.scale(self.zoom / temp, self.zoom / temp) class customScene(QGraphicsScene): - def dragEnterEvent(self, e): - e.acceptProposedAction() - - def dropEvent(self, e): - # find item at these coordinates - item = self.itemAt(e.scenePos()) - if item.setAcceptDrops == True: - # pass on event to item at the coordinates - try: - item.dropEvent(e) - except RuntimeError: - pass #This will supress a Runtime Error generated when dropping into a widget with no MyProxy - - def dragMoveEvent(self, e): - e.acceptProposedAction() + """ + re-implement QGraphicsScene for future functionality + hint: QUndoFramework + """ + pass \ No newline at end of file diff --git a/src/main/python/utils/toolbar.py b/src/main/python/utils/toolbar.py index 6f276df..ec3b6a8 100644 --- a/src/main/python/utils/toolbar.py +++ b/src/main/python/utils/toolbar.py @@ -9,78 +9,80 @@ from .data import toolbarItems from .funcs import grouper from .layout import flowLayout - -resourceManager = ApplicationContext() +resourceManager = ApplicationContext() #Used to load images, mainly toolbar icons class toolbar(QDockWidget): - toolbuttonClicked = pyqtSignal(dict) + """ + Defines the right side toolbar, using QDockWidget. + """ + toolbuttonClicked = pyqtSignal(dict) #signal for any object button pressed def __init__(self, parent = None): super(toolbar, self).__init__(parent) - self.toolbarButtonDict = dict() - self.toolbarItems(toolbarItems.keys()) + self.toolbarButtonDict = dict() #initializes empty dict to store toolbar buttons + self.toolbarItems(toolbarItems.keys()) #creates all necessary buttons self.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) + #mainly used to disable closeability of QDockWidget + #declare main widget and layout self.widget = QWidget(self) self.layout = QBoxLayout(QBoxLayout.TopToBottom, self.widget) self.setAllowedAreas(Qt.AllDockWidgetAreas) - self.searchBox = QLineEdit(self.widget) + self.searchBox = QLineEdit(self.widget) #search box to search through componenets + #connect signal to filter slot, add searchbar to toolbar self.searchBox.textChanged.connect(self.searchQuery) self.layout.addWidget(self.searchBox, alignment=Qt.AlignHCenter) + #create a scrollable area to house all buttons self.diagArea = QScrollArea(self) self.layout.addWidget(self.diagArea) - self.diagAreaWidget = QWidget() + self.diagAreaWidget = QWidget(self.diagArea) #inner widget for scroll area + #custom layout for inner widget self.diagAreaLayout = flowLayout(self.diagAreaWidget) - - self.setWidget(self.widget) + + # self.diagArea.setWidget() #set inner widget to scroll area + self.setWidget(self.widget) #set main widget to dockwidget def clearLayout(self): + # used to clear all items from toolbar, by parenting it to the toolbar instead + # this works because changing parents moves widgets to be the child of the new + # parent, setting it to none, would have qt delete them to free memory for i in reversed(range(self.diagAreaLayout.count())): + # since changing parent would effect indexing, its important to go in reverse self.diagAreaLayout.itemAt(i).widget().setParent(self) def populateToolbar(self, list): - self.clearLayout() + #called everytime the button box needs to be updated(incase of a filter) + self.clearLayout() #clears layout for item in list: self.diagAreaLayout.addWidget(self.toolbarButtonDict[item]) - self.diagArea.setWidget(self.diagAreaWidget) def searchQuery(self): # shorten toolbaritems list with search items # self.populateToolbar() # populate with toolbar items - text = self.searchBox.text() + text = self.searchBox.text() #get text if text == '': - self.populateToolbar(self.toolbarItemList) + self.populateToolbar(self.toolbarItemList) # restore everything on empty string else: + # use regex to search filter through button list and add the remainder to toolbar self.populateToolbar(filter(lambda x: search(text, x, IGNORECASE), self.toolbarItemList)) def resize(self): - parent = self.parentWidget() - if parent.dockWidgetArea in [Qt.TopDockWidgetArea, Qt.BottomDockWidgetArea] and not self.isFloating(): - self.layout.setDirection(QBoxLayout.LeftToRight) - self.setFixedHeight(.12*parent.height()) - self.setFixedWidth(parent.width()) - self.diagAreaWidget.setFixedHeight(.12*parent.height() - 45) - else: - self.layout.setDirection(QBoxLayout.TopToBottom) - self.setFixedWidth(.12*parent.width()) - self.setFixedHeight(self.height()) - self.diagAreaWidget.setFixedWidth(.12*parent.width() - 45) - - def resizeEvent(self, event): - parent = self.parentWidget() - self.layout.setDirection(QBoxLayout.TopToBottom) - self.setFixedWidth(.12*parent.width()) - self.setFixedHeight(self.height()) - width = .12*parent.width() - 45 - self.diagAreaWidget.setFixedWidth(width) + # called when main window resizes, overloading resizeEvent caused issues. + parent = self.parentWidget() #used to get parent dimensions + self.layout.setDirection(QBoxLayout.TopToBottom) # here so that a horizontal toolbar can be implemented later + self.setFixedWidth(.12*parent.width()) #12% of parent width + self.setFixedHeight(self.height()) #span available height + width = .12*parent.width() #12% of parent width + self.diagAreaWidget.setFixedWidth(width) #set inner widget width + # the following line, sets the required height for the current width, so that blank space doesnt occur self.diagAreaWidget.setFixedHeight(self.diagAreaLayout.heightForWidth(width)) - return super(toolbar, self).resizeEvent(event) def toolbarItems(self, items): + #helper functions to create required buttons for item in items: obj = toolbarItems[item] button = toolbarButton(self, obj) @@ -89,39 +91,48 @@ class toolbar(QDockWidget): @property def toolbarItemList(self): + #generator to iterate over all buttons for i in self.toolbarButtonDict.keys(): yield i class toolbarButton(QToolButton): - + """ + Custom buttons for components that implements drag and drop functionality + item -> dict from toolbarItems dict, had 4 properties, name, object, icon and default arguments. + """ def __init__(self, parent = None, item = None): super(toolbarButton, self).__init__(parent) + #uses fbs resource manager to get icons self.setIcon(QIcon(resourceManager.get_resource(f'toolbar/{item["icon"]}'))) - self.setIconSize(QSize(40, 40)) - self.dragStartPosition = 0 - self.itemObject = item['object'] - self.setText(item["name"]) - self.setToolTip(item["name"]) + self.setIconSize(QSize(40, 40)) #unecessary but left for future references + self.dragStartPosition = None #intialize value for drag event + self.itemObject = item['object'] #refer current item object, to handle drag mime + self.setText(item["name"]) #button text + self.setToolTip(item["name"]) #button tooltip def mousePressEvent(self, event): + #check if button was pressed or there was a drag intent super(toolbarButton, self).mousePressEvent(event) if event.button() == Qt.LeftButton: - self.dragStartPosition = event.pos() + self.dragStartPosition = event.pos() #set dragstart position def mouseMoveEvent(self, event): + #handles drag if not (event.buttons() and Qt.LeftButton): - return + return #ignore if left click is not held if (event.pos() - self.dragStartPosition).manhattanLength() < QApplication.startDragDistance(): - return + return #check if mouse was dragged enough, manhattan length is a rough and quick method in qt - drag = QDrag(self) - mimeData = QMimeData() - mimeData.setText(self.itemObject) - drag.setMimeData(mimeData) - drag.exec(Qt.CopyAction) + drag = QDrag(self) #create drag object + mimeData = QMimeData() #create drag mime + mimeData.setText(self.itemObject) # set mime value for view to accept + drag.setMimeData(mimeData) # attach mime to drag + drag.exec(Qt.CopyAction) #execute drag def sizeHint(self): + #defines button size return self.minimumSizeHint() def minimumSizeHint(self): + #defines button size return QSize(30, 30) \ No newline at end of file -- cgit