Skip to content
Snippets Groups Projects
Commit 10060300 authored by Johannes Kung's avatar Johannes Kung
Browse files

Started working on a general graphical module widget

parent b6c3f98f
No related branches found
No related tags found
1 merge request!45General gui module
Pipeline #134428 failed
from typing import Any
from qtpy.QtCore import Property, QPointF, QRectF, Qt, Slot
from qtpy.QtGui import QBrush, QColor, QFont, QFontMetrics, QPainter, QPainterPath, QPen
from qtpy.QtCore import Signal as pyqtSignal
from qtpy.QtCore import Slot
from qtpy.QtWidgets import (
QGraphicsItem,
QGraphicsWidget,
QStyleOptionGraphicsItem,
QWidget,
QAction,
)
from simudator.core.module import Module
class ModuleWidget(QGraphicsWidget):
DEFAULT_WIDTH = 50*3
DEFAULT_HEIGHT = 50*3
update = pyqtSignal()
def __init__(self, module: Module, state_vars: list[str], actions: list[QAction], formatters: dict[str, Any], parent: QGraphicsItem | None = None, flags: Qt.WindowFlags | Qt.WindowType = Qt.WindowFlags()) -> None:
super().__init__(parent, flags)
super().__init__(parent, flags)
self.setFlag(QGraphicsItem.ItemIsMovable)
self._module = module
self._state_vars = state_vars
self._actions = actions
self._formatters = formatters
# Default values for properties for appearance
# TODO: Put these values in constants?
self._outline_width = 1
self._outline = self.palette().windowText()
self._background = self.palette().window()
self._text_color = self.palette().windowText().color()
self._text_font = QFont("Sans Serif", 9)
self._padding = 5
width = self.DEFAULT_WIDTH
height = self.DEFAULT_HEIGHT
if len(self._state_vars) <= 1:
height = QFontMetrics(self._text_font).height() + 2*self._padding
else:
height = (self._padding + QFontMetrics(self._text_font).height()) * (len(state_vars) + 1) + self._padding
self.resize(width, height)
def paint(
self,
painter: QPainter | None = None,
option: QStyleOptionGraphicsItem | None = None,
widget: QWidget | None = None,
) -> None:
painter.save()
width = self.size().width()
height = self.size().height()
# Draw the base shape
pen = QPen(self.outline, self.outline_width)
painter.setPen(pen)
painter.setBrush(self.background)
painter.drawPath(self.shape())
# Set text specific painter settings
painter.setPen(QPen(self.text_color))
painter.setBrush(QBrush(self.text_color))
painter.setFont(self.text_font)
text_flags = Qt.AlignmentFlag.AlignCenter | Qt.TextFlag.TextWordWrap
text_rect = self.shape().boundingRect()
# Draw only name of the module if no state variables are to be shown
if len(self._state_vars) == 0:
painter.drawText(text_rect, text_flags, self._module.get_state()["name"])
# Special case: only 1 state variable to show
elif len(self._state_vars) == 1:
value = self._module.get_state()[self._state_vars[0]]
painter.drawText(text_rect, text_flags, f"{self._module.get_state()["name"]}: {value}")
# Draw the name of the module and each state variable with its value on one row each
else:
text_rect = QRectF(0, 0, width, height/(len(self._state_vars)+1))
painter.drawText(text_rect, text_flags, self._module.get_state()["name"])
for i, state_var in enumerate(self._state_vars):
y_start = height / (len(self._state_vars)+1) * (i+1)
y_end = height / (len(self._state_vars) + 1 )
text_rect = QRectF(0, y_start, width, y_end)
value = self._module.get_state()[state_var]
painter.drawText(text_rect, text_flags, f"{state_var}: {value}")
painter.restore()
@Slot()
def update(self, rect: QRectF | None = None):
# This "override" is needed in order to decorate update() as a
# pyqt slot
super().update()
def shape(self) -> QPainterPath:
path = QPainterPath()
path.addRect(0, 0, self.size().width(), self.size().height())
return path
def boundingRect(self) -> QRectF:
width = self.size().width()
height = self.size().height()
margin = self.outline_width / 2
return QRectF(0 - margin, 0 - margin, width + margin, height + margin)
def outline_width(self) -> float:
"""Return the outline pen width.
Returns
-------
float
Outline pen width.
"""
return self._outline_width
def set_outline_width(self, width: float) -> None:
"""Set the outline pen width.
Parameters
----------
width : float
Outline pen width.
"""
self._outline_width = width
def outline(self) -> QBrush:
"""Return the outline brush used to create the outline pen.
Returns
-------
QBrush
Outline brush.
"""
return self._outline
def set_outline(self, brush: QBrush) -> None:
"""Set the outline brush used to create the outline pen.
Parameters
----------
brush : QBrush
Outline brush.
"""
self._outline = brush
def background(self) -> QBrush:
"""Return the bursh used for filling the background.
Returns
-------
QBrush
Background brush.
"""
return self._background
def set_background(self, brush: QBrush) -> None:
"""Set the bursh used for filling the background.
Parameters
----------
brush : QBrush
Background brush.
"""
self._background = brush
def text_color(self) -> QColor:
"""Return the color used for text.
Returns
-------
QColor
Text color.
"""
return self._text_color
def set_text_color(self, color: QColor) -> None:
"""Set the color used for text.
Parameters
----------
color : QColor
Text color.
"""
self._text_color = color
def text_font(self) -> QFont:
"""Return the font used for text.
Returns
-------
QFont
Text font.
"""
return self._text_font
def set_text_font(self, font: QFont) -> None:
"""Set the font used for text.
Parameters
----------
font : QFont
Text font.
"""
self._text_font = font
outline_width = Property(float, outline_width, set_outline_width)
outline = Property(QBrush, outline, set_outline)
background = Property(QBrush, background, set_background)
text_color = Property(QColor, text_color, set_text_color)
text_font = Property(QFont, text_font, set_text_font)
\ No newline at end of file
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