Skip to content
Snippets Groups Projects
Commit 025efb0d authored by Thomas Holene Løkkeborg's avatar Thomas Holene Løkkeborg
Browse files

#119 ryddet opp inline edit view

- lint fix og docstrings
parent dfc15348
No related branches found
No related tags found
1 merge request!66#119 Støtte utskrift av flere eksemplarer
Pipeline #82447 passed
......@@ -10,22 +10,53 @@ from PySide2.QtWidgets import (
QGraphicsRectItem,
QGraphicsProxyWidget,
)
from PySide2.QtGui import QFont, QPixmap, QBrush, QPalette, QPainter, QTransform
from PySide2.QtGui import (
QFont,
QPixmap,
QBrush,
QPalette,
QPainter,
)
from PySide2.QtPrintSupport import QPrinter
from soitool.soi import ModuleLargerThanBinError
from soitool.dialog_wrappers import exec_warning_dialog
from soitool.serialize_export_import_soi import generate_soi_filename
class ProxyLabelWithConditionalPainting(QGraphicsProxyWidget):
class ProxyLabelWithCustomQPrintText(QGraphicsProxyWidget):
"""QGraphicsItem that prints a custom text when printed onto QPrint.
Useful to have a piece of text be painted differently in a QGraphicsScene
depending on whether it's drawn to QPrint or not.
Note that this class doesn't have to use a QLabel. It was done to KISS.
## How it works
When the QGrahpicsScene wants to render it's items it first uses the
"bounding rects" of it's items to figure out which of them needs to be
redrawn. It then redraws items using their `paint` functions. By overriding
`paint` we can control how our item is drawn. One of the parameters to the
`paint` function is the QPainter that is being used, which we can use to
print custom text onto QPrinter
Parameters
----------
default_text : str
Text to be drawn for all QPainters except QPrint
printing_text : str
Text to be drawn if the QPainters QPrint
"""
def __init__(self, default_text, printing_text):
super(ProxyLabelWithConditionalPainting, self).__init__()
super(ProxyLabelWithCustomQPrintText, self).__init__()
self.default_text = default_text
self.printing_text = printing_text
# self.boundingRect is updated at the end of this function, so this
# default value is in practice never used.
self.bounding_rect = QRectF(0,0,0,0)
self.bounding_rect = QRectF(0, 0, 0, 0)
self.label = QLabel(self.default_text)
self.setWidget(self.label)
......@@ -46,7 +77,7 @@ class ProxyLabelWithConditionalPainting(QGraphicsProxyWidget):
Because of this we're returning a rectangle (starting at 0,0) that
encapsulates the self.widget(), seen from this items local coordinate
system. This class purposefully lets self.widget() have different
content depending on the QPaintDevice, so we give a bounding rect that
content depending on the QPainter, so we give a bounding rect that
encapsulates the largest content.
Returns
......@@ -55,8 +86,12 @@ class ProxyLabelWithConditionalPainting(QGraphicsProxyWidget):
Bounding rect that enpasulates both alternative contents of
self.widget()
"""
bounding_rect_default_text = self.label.fontMetrics().boundingRect(self.default_text)
bounding_rect_printing_text = self.label.fontMetrics().boundingRect(self.printing_text)
bounding_rect_default_text = self.label.fontMetrics().boundingRect(
self.default_text
)
bounding_rect_printing_text = self.label.fontMetrics().boundingRect(
self.printing_text
)
largest_width = max(
bounding_rect_default_text.width(),
bounding_rect_printing_text.width(),
......@@ -65,28 +100,47 @@ class ProxyLabelWithConditionalPainting(QGraphicsProxyWidget):
bounding_rect_default_text.height(),
bounding_rect_printing_text.height(),
)
return QRectF(0,0,largest_width, largest_height)
return QRectF(0, 0, largest_width, largest_height)
def paint(self, painter, option, widget):
"""
"""Overridden to paint text depending on `painter` parameter.
Source: https://doc.qt.io/qt-5/qgraphicsitem.html#paint
Parameter
---------
painter : QPainter
QPainter that is painting the item. Used to determine which text
to draw.
option : QStyleOptionGraphicsItem
Passed on to superclass implementation. See source.
widget : QWidget
Passed on to superclass implementation. See source.
"""
if isinstance(painter.device(), QPrinter):
self.label.setText(self.printing_text)
else:
self.label.setText(self.default_text)
# TODO TODO TODO https://stackoverflow.com/a/49910888/3545896
# See: https://stackoverflow.com/a/47037607/3545896
# From Qt docs: "Prepares the item for a geometry change. Call this
# function before changing the bounding rect of an item to keep
# QGraphicsScene's index up to date."
# https://doc.qt.io/qt-5/qgraphicsitem.html#prepareGeometryChange
self.prepareGeometryChange()
# QLabel doesn't adjust it size automatically, so do it here
# https://stackoverflow.com/a/47037607/3545896
self.label.adjustSize()
super(ProxyLabelWithConditionalPainting, self).paint(painter, option, widget)
# Let super handle the actual painting
super(ProxyLabelWithCustomQPrintText, self).paint(
painter, option, widget
)
def boundingRect(self):
"""Give QRectF that bounds this item. Overriden.
"""Give QRectF that bounds this item. Overridden.
Overriden to provide custom bounding rect. Custom bounding rect is
Overridden to provide custom bounding rect. Custom bounding rect is
needed because this item has two different contents depending on where
it is drawn, which Qt does not respect (or understand) out of the box.
Overrides this: https://doc.qt.io/qt-5/qgraphicsitem.html#boundingRect
......@@ -109,7 +163,13 @@ class ProxyLabelWithConditionalPainting(QGraphicsProxyWidget):
class InlineEditableSOIView(QScrollArea):
"""Widget som kan byttes ut med view, edit etc."""
"""Widget that allows for "inline" editing of an SOI. Also prints to PDF.
Paramters
---------
soi : soitool.SOI
SOI to edit.
"""
def is_widget_in_scene(self, widget):
"""Indicate wether given widget already has a proxy in the scene."""
......@@ -156,7 +216,13 @@ class InlineEditableSOIView(QScrollArea):
self.number_of_pages = 1
self.proxies = set()
# NOTE: These variables are only included to support PDF output of the widget. When rendering self.scene onto a QPrinter this widget will use these variables to indicate that "copy number self.copy_current is being printed, out of a total of self.copy_total copies". By looping self.copy_total times, updating self.copy_current each time and rendering onto a QPrinter it is possible to print multiple copies of the SOI, each marked with a copy number.
# NOTE: These variables are only included to support PDF output of the
# widget. When rendering self.scene onto a QPrinter this widget will
# use these variables to indicate that "copy number self.copy_current
# is being printed, out of a total of self.copy_total copies". By
# looping self.copy_total times, updating self.copy_current each time
# and rendering onto a QPrinter it is possible to print multiple
# copies of the SOI, each marked with a copy number.
self.copy_current = 1
self.copy_total = 3
......@@ -229,7 +295,7 @@ class InlineEditableSOIView(QScrollArea):
)
for i in range(self.copy_total):
# Update copy number and redraw pages so that it is reflected
# in the scene
self.copy_current = i + 1
......@@ -357,9 +423,13 @@ class InlineEditableSOIView(QScrollArea):
# NOTE: See __init__ for explanation on self.copy_current and
# self.copy_total
proxy = ProxyLabelWithConditionalPainting("1 av N", f"{self.copy_current} av {self.copy_total}")
proxy = ProxyLabelWithCustomQPrintText(
"1 av N", f"{self.copy_current} av {self.copy_total}"
)
proxy.label.setStyleSheet("background-color: rgba(0,0,0,0%)")
proxy.label.setFont(QFont("Times New Roman", 40))
# need to call this when label of proxy changes. See function docstring
proxy.update_bounding_rect()
# Source: https://stackoverflow.com/a/8638114/3545896
......@@ -369,7 +439,7 @@ class InlineEditableSOIView(QScrollArea):
)
# NOTE that this position is only correct for the default text. During
# PDF printing the ProxyLabelWithConditionalPainting class will paint
# PDF printing the ProxyLabelWithCustomQPrintText class will paint
# itself with a different text, and thus not be perfectly centered.
proxy.setPos(x + 18, copy_number_y_pos + label_width / 2)
proxy.setRotation(-90)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment