Source code for optimeed.visualize.gui.widgets.widget_line_drawer
from PyQt5 import QtCore, QtGui, QtWidgets
[docs]class widget_line_drawer(QtWidgets.QWidget):
"""Widget allowing to display several lines easily"""
# listOfLines[i] = [x_1, y_1, x_2, y_2]
def __init__(self, minWinHeight=300, minWinWidth=300, is_light=True):
super().__init__()
# Set windows width
self.setMinimumHeight(minWinHeight)
self.setMinimumWidth(minWinWidth)
# Set background colour
p = self.palette()
self.is_light = is_light
if self.is_light:
p.setColor(self.backgroundRole(), QtCore.Qt.white)
else:
p.setColor(self.backgroundRole(), QtCore.Qt.black)
self.setPalette(p)
self.setAutoFillBackground(True)
# Set objects to draw
self.dict_listOfLines = {}
self.dict_pens = {}
self.signal_must_update.connect(self.on_update_signal)
[docs] def delete_lines(self, key_id):
"""
Dele the lines
:param key_id: id to delete
:return:
"""
del self.dict_listOfLines[key_id]
del self.dict_pens[key_id]
[docs] def set_lines(self, listOfLines, key_id=0, pen=None):
"""
Set the lines to display
:param listOfLines: list of [x1, y1, x2, y2] corresponding to lines
:param key_id: id of the trace
:param pen: pen used to draw the lines
:return:
"""
for k, line in enumerate(listOfLines):
if len(line) == 6: # Coordinates are (x,y,z) and not (x,y) -> compress
listOfLines[k] = [line[0], line[1], line[3], line[4]]
self.dict_listOfLines[key_id] = listOfLines
if pen is None:
if self.is_light:
self.dict_pens[key_id] = QtGui.QPen(QtCore.Qt.black, 1)
else:
self.dict_pens[key_id] = QtGui.QPen(QtCore.Qt.white, 1)
else:
self.dict_pens[key_id] = pen
self.repaint()
self.update()
[docs] def paintEvent(self, event, painter=None):
if painter is None:
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
x_min, x_max, y_min, y_max = self.get_extrema_lines()
min_margin = 20
maxwidth = x_max - x_min
maxheight = y_max - y_min
width_window = self.rect().width()
height_window = self.rect().height()
try:
ratio_width = (width_window - min_margin * 2) / maxwidth
ratio_height = (height_window - min_margin * 2) / maxheight
except ZeroDivisionError:
ratio_width = 1
ratio_height = 1
ratio = min(ratio_width, ratio_height)
center_x = (width_window + min_margin * 2 - ratio * maxwidth) / 2
painter.translate(-min_margin + center_x - x_min * ratio, -(min_margin - y_min * ratio) + height_window)
for key in self.dict_listOfLines:
# Set painters and objects to draw
thePen = self.dict_pens[key]
thePen.setWidthF(2)
painter.setPen(thePen)
for line in self.dict_listOfLines[key]:
painter.drawLine(line[0]*ratio, -line[1]*ratio, line[2]*ratio, -line[3]*ratio)
thePen.setWidthF(0.5)
painter.setPen(thePen)
painter.drawLine(0, 0, x_max * ratio, 0)
painter.drawLine(0, 0, 0, -y_max * ratio)
[docs] def get_extrema_lines(self):
x_min, x_max, y_min, y_max = 0, 1e-12, 0, 1e-12
for i, key in enumerate(self.dict_listOfLines):
try:
x_min_temp = min(min(x[0], x[2]) for x in self.dict_listOfLines[key])
x_max_temp = max(max(x[0], x[2]) for x in self.dict_listOfLines[key])
y_min_temp = min(min(x[1], x[3]) for x in self.dict_listOfLines[key])
y_max_temp = max(max(x[1], x[3]) for x in self.dict_listOfLines[key])
if i == 0:
x_min = x_min_temp
x_max = x_max_temp
y_min = y_min_temp
y_max = y_max_temp
else:
x_min = min(x_min, x_min_temp)
x_max = max(x_max, x_max_temp)
y_min = min(y_min, y_min_temp)
y_max = max(y_max, y_max_temp)
except (IndexError, ValueError):
pass
return x_min, x_max, y_min, y_max