Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import enum
- import logging
- import sys
- from functools import lru_cache
- from re import search
- from typing import Any, ItemsView, Match, Sequence
- from xml.etree import ElementTree
- from PySide6.QtCore import QEvent, QObject, QPointF, QRect, QRectF, QSize, Qt, Signal
- from PySide6.QtGui import QGuiApplication, QMouseEvent
- from PySide6.QtSvgWidgets import QSvgWidget
- from PySide6.QtWidgets import QApplication, QLayout, QLayoutItem, QWidget
- CLICK_TOLERANCE: float = 0.05
- # NB: There should be no empty line at the beginning, hence the backslash after the triple quotes.
- SVG_DATA: str = """\
- <?xml version="1.0" encoding="UTF-8" standalone="no"?>
- <!-- Created in defiance of Inkscape (http://www.inkscape.org/) -->
- <svg viewBox="0 0 276 332"
- version="1.1"
- style="stroke-width:0.5px;font-size:8px;font-family:sans-serif;
- --foreground:#000;--background:#fff;
- --air:#26788c;--low-vacuum:#8c268c;--high-vacuum:var(--foreground);
- --undefined-color:#8c8c8c;--off-color:#bf4040;--on-color:#40a6bf;--fault-color:#ff1a1a;"
- xmlns="http://www.w3.org/2000/svg">
- <defs>
- <style>
- /* a hotfix to center the texts vertically */
- text#x4_text,text#x6_text{transform:translate(0,3)}
- </style>
- <linearGradient id="getting-off-color">
- <stop offset="0.05" stop-color="var(--on-color)"/>
- <stop offset="0.95" stop-color="var(--off-color)"/>
- </linearGradient>
- <linearGradient id="getting-on-color">
- <stop offset="0.05" stop-color="var(--off-color)"/>
- <stop offset="0.95" stop-color="var(--on-color)"/>
- </linearGradient>
- <path id="arrow_end" display="marker"
- vector-effect="non-scaling-stroke"
- d="M -1,-1 L 1,0 L -1,1 z"/>
- <circle id="tiny_circle" display="marker"
- cx="0" cy="0"
- r="1"
- style="fill:white;stroke-width:0.5px;stroke:black"/>
- <path id="valve_template"
- stroke="var(--foreground)"
- vector-effect="non-scaling-stroke"
- d="M -16,-8 V 8 L 16,-8 V 8 Z
- M 0,0 -2,-1 v -3 h -3 v -6 H 5 v 6 H 2 v 3 z
- M 0,0 2,1 V 4 H -2 V 1 Z m -5,-4 v -6 H 5 v 6 z"
- display="block"/>
- <g id="x4_valve_template"
- style="stroke:var(--foreground)">
- <circle cy="0"
- cx="0"
- r="16"
- vector-effect="non-scaling-stroke"/>
- <path style="fill:none;stroke-width:2px;stroke:black"
- d="M 0,-16 A 16,16,0,0,1,16,0
- M 0,16 A 16,16,0,0,1,-16,0"
- transform="scale(0.75)"/>
- <use href="#tiny_circle"
- transform="rotate(0) scale(0.75) translate(16, 0)"/>
- <use href="#tiny_circle"
- transform="rotate(90) scale(0.75) translate(16, 0)"/>
- <use href="#tiny_circle"
- transform="rotate(180) scale(0.75) translate(16, 0)"/>
- <use href="#tiny_circle"
- transform="rotate(270) scale(0.75) translate(16, 0)"/>
- </g>
- <g id="x6_valve_template"
- style="stroke:var(--foreground)">
- <circle cy="0"
- cx="0"
- r="16"
- vector-effect="non-scaling-stroke"/>
- <path style="fill:none;stroke-width:2px;stroke:black"
- d="M 8,-13.85640646055102 A 16,16,0,0,1,16,0
- M -16,0 A 16,16,0,0,1,-8,-13.85640646055102
- M 8,13.85640646055102 A 16,16,0,0,1,-8,13.85640646055102"
- transform="scale(0.75)"/>
- <use href="#tiny_circle"
- transform="rotate(0) scale(0.75) translate(16, 0)"/>
- <use href="#tiny_circle"
- transform="rotate(60) scale(0.75) translate(16, 0)"/>
- <use href="#tiny_circle"
- transform="rotate(120) scale(0.75) translate(16, 0)"/>
- <use href="#tiny_circle"
- transform="rotate(180) scale(0.75) translate(16, 0)"/>
- <use href="#tiny_circle"
- transform="rotate(240) scale(0.75) translate(16, 0)"/>
- <use href="#tiny_circle"
- transform="rotate(300) scale(0.75) translate(16, 0)"/>
- </g>
- <g id="turbo_molecular_pump_template"
- stroke="var(--foreground)">
- <rect width="32" height="32"
- x="-16" y="-16"
- vector-effect="non-scaling-stroke"/>
- <circle cy="0" cx="0"
- r="8"/>
- <path fill="none"
- d="m -6,-4 v 8 m 2,-8 v 8 m 2,-8 v 8 m 2,-8 v 8 m 2,-8 v 8 m 2,-8 v 8 m 2,-8 v 8"/>
- <path fill="none"
- d="m 9,-7 7,7 -7,7"/>
- </g>
- <g id="mechanical_pump_template"
- stroke="var(--foreground)">
- <rect width="32" height="32"
- x="-16" y="-16"
- vector-effect="non-scaling-stroke"/>
- <circle cx="0" cy="0"
- r="8"
- fill="none"/>
- <path fill="none"
- d="m 0,-16 -7,7"/>
- <path fill="none"
- d="m 0,-16 7,7"/>
- <use href="#arrow_end"
- fill="var(--foreground)"
- transform="translate(-7, -9) rotate(135) scale(1.5)"/>
- <use href="#arrow_end"
- fill="var(--foreground)"
- transform="translate(7, -9) rotate(45) scale(1.5)"/>
- </g>
- <use id="undefined_valve"
- href="#valve_template"
- fill="var(--undefined-color)"/>
- <use id="fault_valve"
- href="#valve_template"
- fill="var(--fault-color)"/>
- <use id="closed_valve"
- href="#valve_template"
- fill="var(--off-color)"/>
- <use id="closing_valve"
- href="#valve_template"
- fill="url(#getting-off-color)"/>
- <use id="opened_valve"
- href="#valve_template"
- fill="var(--on-color)"/>
- <use id="opening_valve"
- href="#valve_template"
- fill="url(#getting-on-color)"/>
- <g id="opened_fine_valve"
- style="fill:#bf40bf;stroke:var(--foreground)">
- <path vector-effect="non-scaling-stroke"
- d="M -16,-8 V 8 L 16,-8 V 8 Z
- M 0,0 -2,-1 v -5 h -3 v -6 H 5 v 6 H 2 v 5 z
- M 0,0 2,1 V 2 H -2 V 1 Z m -5,-6 v -6 H 5 v 6 z m 3,7 h 4 m -4,-2 h 4 m -4,-2 h 4 m -4,-2 h 4"/>
- <path d="m 16,-8 8,-4"/>
- <use href="#arrow_end"
- transform="translate(24, -12) rotate(-26.56505117707799) scale(2)"/>
- </g>
- <g id="half_opened_fine_valve"
- style="fill:#71c837;stroke:var(--foreground)">
- <path vector-effect="non-scaling-stroke"
- d="M -16,-8 V 8 L 16,-8 V 8 Z
- M 0,0 -2,-1 v -5 h -3 v -6 H 5 v 6 H 2 v 5 z
- M 0,0 2,1 V 2 H -2 V 1 Z m -5,-6 v -6 H 5 v 6 z m 3,7 h 4 m -4,-2 h 4 m -4,-2 h 4 m -4,-2 h 4"/>
- <path d="m 16,-8 8,-4"/>
- <use href="#arrow_end"
- transform="translate(24, -12) rotate(-26.56505117707799) scale(2)"/>
- </g>
- <g id="closed_fine_valve"
- style="fill:var(--off-color);stroke:var(--foreground)">
- <path vector-effect="non-scaling-stroke"
- d="M -16,-8 V 8 L 16,-8 V 8 Z
- M 0,0 -2,-1 v -3 h -3 v -6 H 5 v 6 H 2 v 3 z
- M 0,0 2,1 V 4 H -2 V 1 Z m -5,-4 v -6 H 5 v 6 z m 3,7 H 2 M -2,1 h 4 m -4,-2 h 4 m -4,-2 h 4"/>
- <path d="m 16,-8 8,-4"/>
- <use href="#arrow_end"
- transform="translate(24, -12) rotate(-26.56505117707799) scale(2)"/>
- </g>
- <use id="x4_valve_undefined"
- href="#x4_valve_template"
- fill="var(--undefined-color)"
- transform="rotate(45)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <use id="x4_valve_fault"
- href="#x4_valve_template"
- fill="var(--fault-color)"
- transform="rotate(45)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <use id="x4_valve_off"
- href="#x4_valve_template"
- fill="var(--background)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <use id="x4_valve_getting_off"
- href="#x4_valve_template"
- fill="var(--background)"
- transform="rotate(45)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <use id="x4_valve_on"
- href="#x4_valve_template"
- fill="var(--background)"
- transform="rotate(90)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <use id="x4_valve_getting_on"
- href="#x4_valve_template"
- fill="var(--background)"
- transform="rotate(45)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <use id="x6_valve_undefined"
- href="#x6_valve_template"
- fill="var(--undefined-color)"
- transform="rotate(30)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <use id="x6_valve_fault"
- href="#x6_valve_template"
- fill="var(--fault-color)"
- transform="rotate(30)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <use id="x6_valve_off"
- href="#x6_valve_template"
- fill="var(--background)"
- transform="rotate(60)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <use id="x6_valve_getting_off"
- href="#x6_valve_template"
- fill="var(--background)"
- transform="rotate(30)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <use id="x6_valve_on"
- href="#x6_valve_template"
- fill="var(--background)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <use id="x6_valve_getting_on"
- href="#x6_valve_template"
- fill="var(--background)"
- transform="rotate(30)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <g id="vacuum_gauge"
- style="stroke:var(--foreground)">
- <circle cy="0"
- cx="0"
- r="8"
- vector-effect="non-scaling-stroke"
- fill="white"/>
- <path style="stroke:black"
- d="M 4,4 -4,-4"/>
- <use href="#arrow_end"
- stroke="black"
- fill="black"
- transform="translate(-4, -4) rotate(-135) scale(1.5)"/>
- </g>
- <use id="turbo_molecular_pump_undefined"
- href="#turbo_molecular_pump_template"
- fill="var(--undefined-color)"/>
- <use id="turbo_molecular_pump_fault"
- href="#turbo_molecular_pump_template"
- fill="var(--fault-color)"/>
- <use id="turbo_molecular_pump_off"
- href="#turbo_molecular_pump_template"
- fill="var(--off-color)"/>
- <use id="turbo_molecular_pump_getting_off"
- href="#turbo_molecular_pump_template"
- fill="url(#getting-off-color)"/>
- <use id="turbo_molecular_pump_on"
- href="#turbo_molecular_pump_template"
- fill="var(--on-color)"/>
- <use id="turbo_molecular_pump_getting_on"
- href="#turbo_molecular_pump_template"
- fill="url(#getting-on-color)"/>
- <use id="mechanical_pump_undefined"
- href="#mechanical_pump_template"
- fill="var(--undefined-color)"/>
- <use id="mechanical_pump_fault"
- href="#mechanical_pump_template"
- fill="var(--fault-color)"/>
- <use id="mechanical_pump_off"
- href="#mechanical_pump_template"
- fill="var(--off-color)"/>
- <use id="mechanical_pump_getting_off"
- href="#mechanical_pump_template"
- fill="url(#getting-off-color)"/>
- <use id="mechanical_pump_on"
- href="#mechanical_pump_template"
- fill="var(--on-color)"/>
- <use id="mechanical_pump_getting_on"
- href="#mechanical_pump_template"
- fill="url(#getting-on-color)"/>
- <g id="tds_undefined"
- fill="var(--undefined-color)">
- <rect width="32" height="32"
- x="-16" y="-16"
- vector-effect="non-scaling-stroke"
- stroke="var(--foreground)"/>
- <path stroke="var(--foreground)" fill="none"
- d="M 2,0
- a 2,2 1 0 0 0.5, 0.5
- a 2,2 0 0 1 0.5, 0.5
- a 3,3 0 0 1 -6 , 0
- a 2,2 0 0 1 0.5,-0.5
- a 2,2 1 0 0 0.5,-0.5
- v -12
- a 2,2 0 0 1 4,0
- v 12"/>
- <path stroke="black" fill="none"
- d="M 0,-11 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2"/>
- </g>
- <g id="tds_fault"
- fill="var(--fault-color)">
- <rect width="32" height="32"
- x="-16" y="-16"
- vector-effect="non-scaling-stroke"
- stroke="var(--foreground)"/>
- <path stroke="var(--foreground)" fill="white"
- d="M 2,0
- a 2,2 1 0 0 0.5, 0.5
- a 2,2 0 0 1 0.5, 0.5
- a 3,3 0 0 1 -6 , 0
- a 2,2 0 0 1 0.5,-0.5
- a 2,2 1 0 0 0.5,-0.5
- v -12
- a 2,2 0 0 1 4,0
- v 12"/>
- <path stroke="black" fill="none"
- d="M 0,-11 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2"/>
- </g>
- <g id="tds_off"
- fill="var(--background)">
- <rect width="32" height="32"
- x="-16" y="-16"
- vector-effect="non-scaling-stroke"
- stroke="var(--foreground)"/>
- <path stroke="var(--foreground)" fill="white"
- d="M 2,0
- a 2,2 1 0 0 0.5, 0.5
- a 2,2 0 0 1 0.5, 0.5
- a 3,3 0 0 1 -6 , 0
- a 2,2 0 0 1 0.5,-0.5
- a 2,2 1 0 0 0.5,-0.5
- v -12
- a 2,2 0 0 1 4,0
- v 12"/>
- <path stroke="var(--foreground)" fill="#2a2aff"
- d="M 2,-2
- v 2
- a 2,2 1 0 0 0.5, 0.5
- a 2,2 0 0 1 0.5, 0.5
- a 3,3 0 0 1 -6 , 0
- a 2,2 0 0 1 0.5,-0.5
- a 2,2 1 0 0 0.5,-0.5
- v -2"/>
- <path stroke="black" fill="none"
- d="M 0,-11 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2"/>
- </g>
- <g id="tds_getting_off"
- fill="var(--background)">
- <rect width="32" height="32"
- x="-16" y="-16"
- vector-effect="non-scaling-stroke"
- stroke="var(--foreground)"/>
- <path stroke="var(--foreground)" fill="white"
- d="M 2,0
- a 2,2 1 0 0 0.5, 0.5
- a 2,2 0 0 1 0.5, 0.5
- a 3,3 0 0 1 -6 , 0
- a 2,2 0 0 1 0.5,-0.5
- a 2,2 1 0 0 0.5,-0.5
- v -12
- a 2,2 0 0 1 4,0
- v 12"/>
- <path stroke="var(--foreground)" fill="#008000"
- d="M 2,-6
- v 6
- a 2,2 1 0 0 0.5, 0.5
- a 2,2 0 0 1 0.5, 0.5
- a 3,3 0 0 1 -6 , 0
- a 2,2 0 0 1 0.5,-0.5
- a 2,2 1 0 0 0.5,-0.5
- v -6"/>
- <path stroke="black" fill="none"
- d="M 0,-11 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2"/>
- </g>
- <g id="tds_on"
- fill="white">
- <rect width="32" height="32"
- x="-16" y="-16"
- vector-effect="non-scaling-stroke"
- stroke="var(--foreground)"/>
- <path stroke="var(--foreground)" fill="white"
- d="M 2,0
- a 2,2 1 0 0 0.5, 0.5
- a 2,2 0 0 1 0.5, 0.5
- a 3,3 0 0 1 -6 , 0
- a 2,2 0 0 1 0.5,-0.5
- a 2,2 1 0 0 0.5,-0.5
- v -12
- a 2,2 0 0 1 4,0
- v 12"/>
- <path stroke="var(--foreground)" fill="#ff2a2a"
- d="M 2,-10
- v 10
- a 2,2 1 0 0 0.5, 0.5
- a 2,2 0 0 1 0.5, 0.5
- a 3,3 0 0 1 -6 , 0
- a 2,2 0 0 1 0.5,-0.5
- a 2,2 1 0 0 0.5,-0.5
- v -10"/>
- <path stroke="black" fill="none"
- d="M 0,-11 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2"/>
- </g>
- <g id="tds_getting_on"
- fill="white">
- <rect width="32" height="32"
- x="-16" y="-16"
- vector-effect="non-scaling-stroke"
- stroke="var(--foreground)"/>
- <path stroke="var(--foreground)" fill="white"
- d="M 2,0
- a 2,2 1 0 0 0.5, 0.5
- a 2,2 0 0 1 0.5, 0.5
- a 3,3 0 0 1 -6 , 0
- a 2,2 0 0 1 0.5,-0.5
- a 2,2 1 0 0 0.5,-0.5
- v -12
- a 2,2 0 0 1 4,0
- v 12"/>
- <path stroke="var(--foreground)" fill="#2aff2a"
- d="M 2,-6
- v 6
- a 2,2 1 0 0 0.5, 0.5
- a 2,2 0 0 1 0.5, 0.5
- a 3,3 0 0 1 -6 , 0
- a 2,2 0 0 1 0.5,-0.5
- a 2,2 1 0 0 0.5,-0.5
- v -6"/>
- <path stroke="black" fill="none"
- d="M 0,-11 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2 m -2,2 h 2"/>
- </g>
- <path id="inlet"
- d="m 0,0 h -8 m 2,4 h -2 v -8 h 2"/>
- <path id="outlet"
- d="m 0,0 h 12 m 0,4 V -4 M 8,4 v -8"/>
- </defs>
- <g id="paths"
- style="fill:none;stroke-width:2px;">
- <path id="cavity-v7_path"
- style="stroke:var(--high-vacuum)"
- d="M 32,285 h 84 v -2 h -84 m 26,4 v -6 h 4 v 6 z m 2,-2 v -32 m 0,32 v 40 h 28 m 14,-38 v -6 h 4 v 6 z m 2,-2 v -32 h 12"/>
- <path id="v1-cavity_path"
- style="stroke:var(--high-vacuum)"
- d="M 88,24 h -12 m -32,0 h -12"/>
- <path id="v7-pump1_path"
- style="stroke:var(--high-vacuum)"
- d="M 148,285 h 24 v -2 h -24 m 10,4 v -6 h 4 v 6 z m 2,-2 v -32 h -12"/>
- <path id="pump1-v6_path"
- style="stroke:var(--high-vacuum)"
- d="M 216,285 l -12 -1 l 12 -1 z"/>
- <path id="v5-x6_path"
- style="stroke:var(--high-vacuum)"
- d="M 120,64 h 24"/>
- <path id="x6-x4-2_path"
- style="stroke:var(--high-vacuum)"
- d="M 160,64 m 8,-13.856406460551018 l 8,-13.856406460551018 h 12 V 124 h -40"/>
- <path id="x6-tds2_path"
- style="stroke:var(--high-vacuum)"
- d="M 160,64 m -8,-13.856406460551018 l -8,-13.856406460551018 V 24 h 80 v 32
- M 160,64 m 8,13.856406460551018 l 8,13.856406460551018 h 8 a 4,4,0,0,1,8,0 h 32 V 80"/>
- <path id="v2-tds1_path"
- style="stroke:var(--high-vacuum)"
- d="M 216,196 h -84 v -12"/>
- <path id="tds1-x4_path"
- style="stroke:var(--high-vacuum)"
- d="M 132,152 v -12"/>
- <path id="x4-v1_path"
- style="stroke:var(--high-vacuum)"
- d="M 132,108 v -12 a 4,4,0,0,0,0,-8 v -20 a 4,4,0,0,0,0,-8 v -36 h -12"/>
- <path id="x6-x4-1_path"
- style="stroke:var(--high-vacuum)"
- d="M 160,64 m -8,13.856406460551018 l -8,13.856406460551018 h -40 V 124 h 12"/>
- <path id="v3-v4_path"
- style="stroke:var(--high-vacuum)"
- d="M 204,164 v -32"/>
- <path id="v2-v3_path"
- style="stroke:var(--high-vacuum)"
- d="M 204,196 v -32"/>
- <path id="v5-pump2_path"
- style="stroke:var(--high-vacuum)"
- d="M 88,64 h -8 M 80,63 h -5 v 154 h 184 v 66 h -12 M 80,65 h -3 v 150 h 184 v 70 h -14 m 10,2 v -6 h 6 v 6 z m 2,-2 v 16 h 2 v -16"/>
- <path id="v4_path"
- style="stroke:var(--high-vacuum)"
- d="M 216,132 h -12"/>
- <path id="v3_path"
- style="stroke:var(--high-vacuum)"
- d="M 216,164 h -12 m -2,2 v -4 h 4 v 4 z"/>
- <path id="v2_path"
- style="stroke:var(--high-vacuum)"
- d="M 216,196 h -12 m -2,2 v -4 h 4 v 4 z"/>
- <use id="v2_inlet"
- href="#inlet"
- style="stroke:var(--air)"
- transform="translate(248,196) rotate(180)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <use id="v3_inlet"
- href="#inlet"
- style="stroke:var(--air)"
- transform="translate(248,164) rotate(180)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <use id="v4_inlet"
- href="#inlet"
- style="stroke:var(--air)"
- transform="translate(248,132) rotate(180)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <use id="v9_outlet"
- href="#outlet"
- style="stroke:var(--air)"
- transform="translate(120,324)"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- </g>
- <g id="cavity"
- transform="translate(16,156) rotate(-90)">
- <rect style="fill:#b2b2b2;stroke:var(--foreground)"
- id="cavity_body"
- width="280"
- height="32"
- x="-140"
- y="-16"
- vector-effect="non-scaling-stroke"/>
- <switch>
- <text id="cavity_text"
- alignment-baseline="middle"
- text-anchor="middle"
- style="fill:black;"
- x="0"
- y="0"
- systemLanguage="de">
- Hohlraum
- </text>
- <text id="cavity_text"
- alignment-baseline="middle"
- text-anchor="middle"
- style="fill:black;"
- x="0"
- y="0">
- cavity
- </text>
- </switch>
- </g>
- <g id="v_fine"
- transform="translate(60,24) scale(-1, 1)">
- <use id="v_fine_body"
- href="#half_opened_fine_valve"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- </g>
- <g id="v1"
- transform="translate(104,24)">
- <use id="v1_body"
- href="#undefined_valve"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <text id="v1_text"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="-16">
- V1
- </text>
- </g>
- <g id="v2"
- transform="translate(232,196)">
- <use id="v2_body"
- href="#undefined_valve"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <text id="v2_text"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="-16">
- V2
- </text>
- </g>
- <g id="v3"
- transform="translate(232,164)">
- <use id="v3_body"
- href="#undefined_valve"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <text id="v3_text"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="-16">
- V3
- </text>
- </g>
- <g id="v4"
- transform="translate(232,132)">
- <use id="v4_body"
- href="#undefined_valve"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <text id="v4_text"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="-16">
- V4
- </text>
- </g>
- <g id="v5"
- transform="translate(104,64)">
- <use id="v5_body"
- href="#undefined_valve"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <text id="v5_text"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="-16">
- V5
- </text>
- </g>
- <g id="v6"
- transform="translate(232,284)">
- <use id="v6_body"
- href="#undefined_valve"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <text id="v6_text"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="-16">
- V6
- </text>
- </g>
- <g id="v8"
- transform="translate(132,252)">
- <use id="v8_body"
- href="#undefined_valve"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <text id="v8_text"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="-16">
- V8
- </text>
- </g>
- <g id="v7"
- transform="translate(132,284)">
- <use id="v7_body"
- href="#undefined_valve"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <text id="v7_text"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="-16">
- V7
- </text>
- </g>
- <g id="v9"
- transform="translate(104,324)">
- <use id="v9_body"
- href="#undefined_valve"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <text id="v9_text"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="-16">
- V9
- </text>
- </g>
- <g id="x4"
- transform="translate(132,124)">
- <use id="x4_body"
- href="#x4_valve_undefined"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <text id="x4_text"
- alignment-baseline="central"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="0">
- X4
- </text>
- </g>
- <g id="x6"
- transform="translate(160,64)">
- <use id="x6_body"
- href="#x6_valve_undefined"
- x="0"
- y="0"
- width="100%"
- height="100%"/>
- <text id="x6_text"
- alignment-baseline="central"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="0">
- X6
- </text>
- </g>
- <g id="p1"
- transform="translate(60,244)">
- <use id="p1_body"
- href="#vacuum_gauge"
- y="0"
- x="0"
- height="100%"
- width="100%"/>
- <text id="p1_text"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="-12">
- P1
- </text>
- <switch>
- <text id="p1_value"
- alignment-baseline="middle"
- text-anchor="start"
- style="fill:var(--foreground);"
- x="10"
- y="0"
- systemLanguage="de">
- atm
- </text>
- <text id="p1_value"
- alignment-baseline="middle"
- text-anchor="start"
- style="fill:var(--foreground);"
- x="10"
- y="0">
- atm
- </text>
- </switch>
- </g>
- <g id="pump1"
- transform="translate(188,284)">
- <use id="pump1_body"
- href="#turbo_molecular_pump_undefined"
- y="0"
- x="0"
- height="100%"
- width="100%"/>
- <switch>
- <text id="pump1_value"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="28"
- systemLanguage="de">
- 0 U/min
- </text>
- <text id="pump1_value"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="28">
- 0 rpm
- </text>
- </switch>
- </g>
- <g id="pump2"
- transform="translate(260,316)">
- <use id="pump2_body"
- href="#mechanical_pump_undefined"
- y="0"
- x="0"
- height="100%"
- width="100%"/>
- </g>
- <g id="tds1"
- transform="translate(132,168)">
- <use id="tds1_body"
- href="#tds_undefined"
- y="0"
- x="0"
- height="100%"
- width="100%"/>
- <switch>
- <text id="tds1_text"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="12"
- systemLanguage="de">
- TDS1
- </text>
- <text id="tds1_text"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="12">
- TDS1
- </text>
- </switch>
- <text id="tds1_value"
- text-anchor="start"
- alignment-baseline="central"
- style="fill:var(--foreground);"
- x="20"
- y="6">
- t°C
- </text>
- <text id="tds1_target"
- text-anchor="start"
- alignment-baseline="central"
- style="fill:var(--foreground);"
- x="20"
- y="-6">
- T°C
- </text>
- </g>
- <g id="tds2"
- transform="translate(224,64)">
- <use id="tds2_body"
- href="#tds_undefined"
- y="0"
- x="0"
- height="100%"
- width="100%"/>
- <switch>
- <text id="tds2_text"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="12"
- systemLanguage="de">
- TDS2
- </text>
- <text id="tds2_text"
- text-anchor="middle"
- style="fill:var(--foreground);"
- x="0"
- y="12">
- TDS2
- </text>
- </switch>
- <text id="tds2_value"
- text-anchor="start"
- alignment-baseline="central"
- style="fill:var(--foreground);"
- x="20"
- y="6">
- t°C
- </text>
- <text id="tds2_target"
- text-anchor="start"
- alignment-baseline="central"
- style="fill:var(--foreground);"
- x="20"
- y="-6">
- T°C
- </text>
- </g>
- </svg>
- """
- def next_item[_T](s: Sequence[_T], current_item: _T) -> _T:
- if not s:
- raise ValueError("The sequence cannot be empty")
- if current_item not in s:
- return s[0]
- return s[(s.index(current_item) + 1) % len(s)]
- class CSS:
- def __init__(self, text: str = "") -> None:
- self._data: dict[str, str] = dict()
- self.update(text)
- def update(self, text: str) -> None:
- text_lines: list[str] = text.split(";")
- line: str
- key: str
- value: str
- for line in text_lines:
- if ":" not in line:
- continue
- key, value = line.split(":", maxsplit=1)
- self._data[key.strip()] = value.strip()
- def items(self) -> ItemsView[str, str]:
- return self._data.items()
- def __str__(self) -> str:
- return "; ".join(f"{key}:{value}" for key, value in self._data.items())
- def __getitem__(self, item: str) -> str:
- if item not in self._data:
- raise KeyError
- return self._data[item]
- def __setitem__(self, key: str, value: str) -> None:
- value = str(value)
- self._data[str(key)] = value
- def __len__(self) -> int:
- return len(self._data)
- def __bool__(self) -> bool:
- return bool(self._data)
- def __contains__(self, item: str) -> bool:
- return item in self._data
- class DeviceState(enum.IntEnum):
- Invalid = -1
- Initialization = 0
- Fault = 1
- Off = 2
- GettingOff = 3
- On = 4
- GettingOn = 5
- class AspectLayout(QLayout):
- """Credits: https://gist.github.com/sjdv1982/75899d10e6983b878f63083e3c47b39b"""
- def __init__(self, aspect: float, parent: QWidget | None = None) -> None:
- self.aspect: float = aspect
- self.item: QLayoutItem | None = None
- super().__init__(parent)
- self.setContentsMargins(0, 0, 0, 0)
- def addItem(self, item: QLayoutItem) -> None:
- assert self.item is None, "AspectLayout can contain only 1 item"
- self.item = item
- def itemAt(self, index: int) -> QLayoutItem | None:
- if index != 0:
- return None
- return self.item
- def takeAt(self, index: int) -> QLayoutItem | None:
- if index != 0:
- return None
- result: QLayoutItem | None = self.item
- self.item = None
- return result
- def setGeometry(self, rect: QRect) -> None:
- super().setGeometry(rect)
- margins: tuple[int, int, int, int] = self.getContentsMargins()
- if self.item is not None:
- available_width: int = rect.width() - margins[1] - margins[3]
- available_height: int = rect.height() - margins[0] - margins[2]
- height: float = available_height
- width: float = height * self.aspect
- x: float
- y: float
- if width > available_width:
- x = margins[1]
- width = available_width
- height = width / self.aspect
- if self.item.alignment() & Qt.AlignmentFlag.AlignTop:
- y = margins[0]
- elif self.item.alignment() & Qt.AlignmentFlag.AlignBottom:
- y = rect.height() - margins[2] - height
- else:
- y = margins[0] + (available_height - height) / 2
- else:
- y = margins[0]
- if self.item.alignment() & Qt.AlignmentFlag.AlignLeft:
- x = margins[1]
- elif self.item.alignment() & Qt.AlignmentFlag.AlignRight:
- x = rect.width() - margins[3] - width
- else:
- x = margins[1] + (available_width - width) / 2
- self.item.widget().setGeometry(
- round(rect.x() + x),
- round(rect.y() + y),
- round(width),
- round(height),
- )
- def sizeHint(self) -> QSize:
- margins: tuple[int, int, int, int] = self.getContentsMargins()
- if self.item is None:
- return QSize(margins[0] + margins[2], margins[1] + margins[3])
- s: QSize = self.item.sizeHint()
- return QSize(
- margins[0] + margins[2] + s.width(),
- margins[1] + margins[3] + s.height(),
- )
- def minimumSize(self) -> QSize:
- margins: tuple[int, int, int, int] = self.getContentsMargins()
- if self.item is None:
- return QSize(margins[0] + margins[2], margins[1] + margins[3])
- s: QSize = self.item.minimumSize()
- return QSize(
- margins[0] + margins[2] + s.width(),
- margins[1] + margins[3] + s.height(),
- )
- def expandingDirections(self) -> Qt.Orientation:
- return Qt.Orientation.Horizontal | Qt.Orientation.Vertical
- def count(self) -> int:
- if self.item is None:
- return 0
- else:
- return 1
- def hasHeightForWidth(self) -> bool:
- return True
- def heightForWidth(self, width: int) -> int:
- margins: tuple[int, int, int, int] = self.getContentsMargins()
- height: float = (
- (width - margins[1] - margins[3]) / self.aspect + margins[0] + margins[2]
- )
- return round(height)
- class Scheme(QWidget):
- toggled: Signal = Signal(str, DeviceState, name="toggled")
- class PipeColor(enum.StrEnum):
- Air = "var(--air)"
- LowVacuum = "var(--low-vacuum)"
- HighVacuum = "var(--high-vacuum)"
- def __init__(self, parent: QWidget | None = None) -> None:
- super().__init__(parent)
- self.svg: ElementTree.Element = ElementTree.XML(SVG_DATA)
- self.svg_namespace: str = self.svg.tag[1 : self.svg.tag.index("}")]
- self.css: CSS = CSS(self.svg.get("style") or "")
- match QGuiApplication.styleHints().colorScheme():
- case Qt.ColorScheme.Light:
- self.css["--foreground"] = "#000"
- self.css["--background"] = "#fff"
- case Qt.ColorScheme.Dark:
- self.css["--foreground"] = "#fff"
- self.css["--background"] = "#000"
- self.svg.set("style", str(self.css))
- layout: AspectLayout = AspectLayout(
- self._view_box().width() / self._view_box().height(), self
- )
- self.svg_widget: QSvgWidget = QSvgWidget(self)
- self.svg_widget.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu)
- layout.addWidget(self.svg_widget)
- self.svg_widget.setMinimumSize(self._view_box().size().toSize())
- self.svg_widget.renderer().setAspectRatioMode(
- Qt.AspectRatioMode.KeepAspectRatio
- )
- self.valve_states: dict[str, DeviceState] = {
- "v1": DeviceState.Initialization,
- "v2": DeviceState.Initialization,
- "v3": DeviceState.Initialization,
- "v4": DeviceState.Initialization,
- "v5": DeviceState.Initialization,
- "v6": DeviceState.Initialization,
- "v7": DeviceState.Initialization,
- "v8": DeviceState.Initialization,
- "v9": DeviceState.Initialization,
- "x4": DeviceState.Initialization,
- "x6": DeviceState.Initialization,
- }
- self.valve_features: dict[str, dict[str, Any]] = {
- "v_fine": {
- "images": {
- DeviceState.Off: "closed_fine_valve",
- DeviceState.On: "opened_fine_valve",
- }
- },
- "x4": {
- "images": {
- DeviceState.Initialization: "x4_valve_undefined",
- DeviceState.Fault: "x4_valve_fault",
- DeviceState.Off: "x4_valve_off",
- DeviceState.GettingOff: "x4_valve_getting_off",
- DeviceState.On: "x4_valve_on",
- DeviceState.GettingOn: "x4_valve_getting_on",
- DeviceState.Invalid: "x4_valve_fault",
- }
- },
- "x6": {
- "images": {
- DeviceState.Initialization: "x6_valve_undefined",
- DeviceState.Fault: "x6_valve_fault",
- DeviceState.Off: "x6_valve_off",
- DeviceState.GettingOff: "x6_valve_getting_off",
- DeviceState.On: "x6_valve_on",
- DeviceState.GettingOn: "x6_valve_getting_on",
- DeviceState.Invalid: "x6_valve_fault",
- }
- },
- }
- self.pump_states: dict[str, DeviceState] = {
- "pump1": DeviceState.Initialization,
- "pump2": DeviceState.Initialization,
- }
- self.pump_features: dict[str, dict[str, Any]] = {
- "pump1": {
- "images": {
- DeviceState.Initialization: "turbo_molecular_pump_undefined",
- DeviceState.Fault: "turbo_molecular_pump_fault",
- DeviceState.Off: "turbo_molecular_pump_off",
- DeviceState.GettingOff: "turbo_molecular_pump_getting_off",
- DeviceState.On: "turbo_molecular_pump_on",
- DeviceState.GettingOn: "turbo_molecular_pump_getting_on",
- DeviceState.Invalid: "turbo_molecular_pump_fault",
- }
- },
- "pump2": {
- "images": {
- DeviceState.Initialization: "mechanical_pump_undefined",
- DeviceState.Fault: "mechanical_pump_fault",
- DeviceState.Off: "mechanical_pump_off",
- DeviceState.GettingOff: "mechanical_pump_getting_off",
- DeviceState.On: "mechanical_pump_on",
- DeviceState.GettingOn: "mechanical_pump_getting_on",
- DeviceState.Invalid: "mechanical_pump_fault",
- }
- },
- }
- self.tds_states: dict[str, DeviceState] = {
- "tds1": DeviceState.Initialization,
- "tds2": DeviceState.Initialization,
- }
- self.tds_features: dict[str, dict[str, Any]] = {
- "tds1": {},
- "tds2": {},
- }
- valve_name: str
- valve_state: DeviceState
- for valve_name, valve_state in self.valve_states.items():
- self.change_valve_state(valve_name, valve_state)
- self.color_paths()
- self.redraw_svg()
- self.adjustSize()
- self.svg_widget.setMouseTracking(False)
- (self.svg_widget.focusProxy() or self.svg_widget).installEventFilter(self)
- self.locked: bool = True
- def eventFilter(self, source: QObject, event: QEvent) -> bool:
- """return True to stop the event processing chain"""
- if isinstance(event, QMouseEvent):
- if not self.locked and event.type() == QEvent.Type.MouseButtonRelease:
- svg_width: float = min(
- float(self.svg_widget.width()),
- self._view_box().width()
- / self._view_box().height()
- * self.svg_widget.height(),
- )
- svg_height: float = min(
- float(self.svg_widget.height()),
- self.svg_widget.width()
- / self._view_box().width()
- * self._view_box().height(),
- )
- x: float = (
- event.position().x() - (self.svg_widget.width() - svg_width) / 2.0
- )
- y: float = (
- event.position().y() - (self.svg_widget.height() - svg_height) / 2.0
- )
- item: str | None = self.item_at(
- QPointF(x / svg_width, y / svg_height), tolerance=CLICK_TOLERANCE
- )
- if item:
- self.toggle_next_state(item)
- return True
- return super().eventFilter(source, event)
- def resolve_css_vars(self, svg: str) -> str:
- for key, value in self.css.items():
- svg = svg.replace(f"var({key})", value)
- while True:
- match: None | Match[str] = search(r"var\((?P<var>--.+?)\)", svg)
- if match is not None:
- svg = svg.replace(
- f'var({match.group("var")})', self.css[match.group("var")]
- )
- else:
- return svg
- def toggle_next_state(self, item_name: str) -> None:
- states: list[DeviceState] = [DeviceState.Off, DeviceState.On]
- next_state: DeviceState
- if item_name in self.valve_states:
- next_state = next_item(states, self.valve_states[item_name])
- self.change_valve_state(item_name, next_state)
- elif item_name in self.pump_states:
- next_state = next_item(states, self.pump_states[item_name])
- self.change_pump_state(item_name, next_state)
- elif item_name in self.tds_states:
- next_state = next_item(states, self.tds_states[item_name])
- self.change_tds_state(item_name, next_state)
- else:
- return
- if __name__ == "__main__":
- self.color_paths()
- self.redraw_svg()
- self.toggled.emit(item_name, next_state)
- @lru_cache(maxsize=None, typed=True)
- def _relative_x_path(self, tag_name: str, **attrs: str) -> str:
- attr_key: str
- attr_value: str
- attrs_string: str = "".join(
- f'[@{attr_key}="{attr_value}"]' for attr_key, attr_value in attrs.items()
- )
- if "{" in tag_name:
- return f"./{tag_name}" + attrs_string
- return f"./{{{self.svg_namespace}}}{tag_name}" + attrs_string
- @lru_cache(maxsize=None, typed=True)
- def _get_inner_items(
- self, item_name: str, tag_name: str, suffix: str
- ) -> list[ElementTree.Element]:
- group: ElementTree.Element | None = self.svg.find(
- self._relative_x_path("g", id=item_name)
- )
- if group is None:
- return []
- text_path: str = self._relative_x_path(
- tag_name=tag_name, id=f"{item_name}_{suffix}"
- )
- elements: list[ElementTree.Element] = group.findall(text_path)
- if elements:
- return elements
- return sum((element.findall(text_path) for element in group), [])
- @lru_cache(maxsize=None, typed=True)
- def _get_body(self, item_name: str) -> ElementTree.Element | None:
- try:
- return self._get_inner_items(item_name, tag_name="use", suffix="body")[0]
- except IndexError:
- return None
- @lru_cache(maxsize=None, typed=True)
- def _get_values(self, item_name: str) -> list[ElementTree.Element]:
- return self._get_inner_items(item_name, tag_name="text", suffix="value")
- @lru_cache(maxsize=None, typed=True)
- def _get_targets(self, item_name: str) -> list[ElementTree.Element]:
- return self._get_inner_items(item_name, tag_name="text", suffix="target")
- @lru_cache(maxsize=None, typed=True)
- def _get_path(self, path_name: str) -> ElementTree.Element | None:
- paths_group: ElementTree.Element | None = self.svg.find(
- self._relative_x_path("g", id="paths")
- )
- if paths_group is None:
- return None
- return paths_group.find(self._relative_x_path("path", id=path_name))
- @lru_cache(maxsize=None, typed=True)
- def _view_box(self) -> QRectF:
- view_box: str | None = self.svg.get("viewBox")
- if not view_box:
- return QRectF()
- return QRectF(*map(float, view_box.split()))
- @lru_cache(maxsize=None, typed=True)
- def _item_location(self, item_name: str) -> QPointF:
- """returns the relative location of an item on the scheme"""
- element: ElementTree.Element | None = self.svg.find(
- self._relative_x_path("g", id=item_name)
- )
- if element is None:
- return QPointF()
- if "transform" not in element.attrib:
- return QPointF()
- transform: str | None = element.get("transform")
- if not transform:
- return QPointF()
- translate_match: Match[str] | None = search(
- r"translate\s*\((?P<x>\d*\.?\d*),[\s\n]*(?P<y>\d*\.?\d*)\)",
- transform.casefold(),
- )
- if translate_match is None:
- return QPointF()
- view_box: QRectF = self._view_box()
- translate: QPointF = QPointF(
- float(translate_match.group("x")), float(translate_match.group("y"))
- )
- return QPointF(
- (translate.x() - view_box.x()) / view_box.width(),
- (translate.y() - view_box.y()) / view_box.height(),
- )
- def item_at(self, point: QPointF, tolerance: float) -> str | None:
- element: ElementTree.Element
- for element in self.svg.iterfind(self._relative_x_path("g")):
- if "id" not in element.attrib:
- continue
- element_position: QPointF = self._item_location(element.get("id"))
- if element_position.isNull():
- continue
- if (
- abs(element_position.x() - point.x()) < tolerance
- and abs(element_position.y() - point.y()) < tolerance
- ):
- return element.get("id")
- return None
- def change_valve_state(self, valve_name: str, new_state: DeviceState) -> None:
- valve_name = valve_name.casefold()
- images: dict[DeviceState, str] = {
- DeviceState.Initialization: "undefined_valve",
- DeviceState.Fault: "fault_valve",
- DeviceState.Off: "closed_valve",
- DeviceState.GettingOff: "closing_valve",
- DeviceState.On: "opened_valve",
- DeviceState.GettingOn: "opening_valve",
- DeviceState.Invalid: "fault_valve",
- }
- images.update(self.valve_features.get(valve_name, dict()).get("images", dict()))
- valve_body: ElementTree.Element | None = self._get_body(valve_name)
- if valve_body is None:
- return
- if new_state in images:
- valve_body.set("href", "#" + images[new_state])
- else:
- valve_body.set("href", "")
- self.valve_states[valve_name] = new_state
- def change_pump_state(self, pump_name: str, new_state: DeviceState) -> None:
- pump_name = pump_name.casefold()
- images: dict[DeviceState, str] = {
- DeviceState.Initialization: "pump_undefined",
- DeviceState.Fault: "pump_fault",
- DeviceState.Off: "pump_off",
- DeviceState.GettingOff: "pump_getting_off",
- DeviceState.On: "pump_on",
- DeviceState.GettingOn: "pump_getting_on",
- DeviceState.Invalid: "pump_fault",
- }
- images.update(self.pump_features.get(pump_name, dict()).get("images", dict()))
- pump_body: ElementTree.Element | None = self._get_body(pump_name)
- if pump_body is None:
- return
- pump_body.set("href", "#" + images[new_state])
- self.pump_states[pump_name] = new_state
- def change_tds_state(self, tds_name: str, new_state: DeviceState) -> None:
- tds_name = tds_name.casefold()
- images: dict[DeviceState, str] = {
- DeviceState.Initialization: "tds_undefined",
- DeviceState.Fault: "tds_fault",
- DeviceState.Off: "tds_off",
- DeviceState.GettingOff: "tds_getting_off",
- DeviceState.On: "tds_on",
- DeviceState.GettingOn: "tds_getting_on",
- DeviceState.Invalid: "tds_fault",
- }
- images.update(self.tds_features.get(tds_name, dict()).get("images", dict()))
- tds_body: ElementTree.Element | None = self._get_body(tds_name)
- if tds_body is None:
- return
- tds_body.set("href", "#" + images[new_state])
- self.tds_states[tds_name] = new_state
- def write_value(self, item_name: str, value: str) -> None:
- for item_text in self._get_values(item_name):
- item_text.text = value
- def write_target(self, item_name: str, value: str) -> None:
- for item_text in self._get_targets(item_name):
- item_text.text = value
- def color_path(self, path_name: str, color: str) -> None:
- path: ElementTree.Element | None = self._get_path(path_name)
- if path is None:
- logging.warning(f"path {path_name!r} missing")
- return
- style: CSS = CSS(path.get("style") or "")
- style["stroke"] = color
- path.set("style", str(style))
- def redraw_svg(self) -> None:
- self.svg_widget.load(
- self.resolve_css_vars(ElementTree.tostring(self.svg).decode()).encode()
- )
- def color_paths(self) -> None:
- if (
- self.valve_states["v2"] == DeviceState.On
- or self.valve_states["v3"] == DeviceState.On
- or self.valve_states["v4"] == DeviceState.On
- ):
- if self.valve_states["v2"] == DeviceState.On:
- self.color_path("v2_path", Scheme.PipeColor.Air)
- elif self.valve_states["v2"] == DeviceState.Off:
- self.color_path("v2_path", Scheme.PipeColor.HighVacuum)
- if self.valve_states["v3"] == DeviceState.On:
- self.color_path("v3_path", Scheme.PipeColor.Air)
- self.color_path("v2-v3_path", Scheme.PipeColor.Air)
- elif self.valve_states["v3"] == DeviceState.Off:
- self.color_path("v3_path", Scheme.PipeColor.HighVacuum)
- if self.valve_states["v4"] == DeviceState.On:
- self.color_path("v4_path", Scheme.PipeColor.Air)
- self.color_path("v2-v3_path", Scheme.PipeColor.Air)
- self.color_path("v3-v4_path", Scheme.PipeColor.Air)
- elif self.valve_states["v4"] == DeviceState.Off:
- self.color_path("v4_path", Scheme.PipeColor.HighVacuum)
- self.color_path("v3-v4_path", Scheme.PipeColor.HighVacuum)
- if self.valve_states["v3"] == DeviceState.Off:
- self.color_path("v2-v3_path", Scheme.PipeColor.HighVacuum)
- self.color_path("v2-tds1_path", Scheme.PipeColor.Air)
- self.color_path("tds1-x4_path", Scheme.PipeColor.Air)
- if self.valve_states["x4"] == DeviceState.Off:
- self.color_path("x6-x4-1_path", Scheme.PipeColor.Air)
- if self.valve_states["x6"] == DeviceState.On:
- self.color_path("x6-tds2_path", Scheme.PipeColor.Air)
- self.color_path("v5-x6_path", Scheme.PipeColor.Air)
- if self.valve_states["v5"] == DeviceState.On:
- self.color_path("v5-pump2_path", Scheme.PipeColor.Air)
- if self.valve_states["v6"] == DeviceState.On:
- self.color_path("pump1-v6_path", Scheme.PipeColor.Air)
- self.color_path("v7-pump1_path", Scheme.PipeColor.Air)
- if (
- self.valve_states["v7"] == DeviceState.On
- or self.valve_states["v8"] == DeviceState.On
- ):
- self.color_path("cavity-v7_path", Scheme.PipeColor.Air)
- self.color_path("v1-cavity_path", Scheme.PipeColor.Air)
- if self.valve_states["v1"] == DeviceState.On:
- self.color_path("x4-v1_path", Scheme.PipeColor.Air)
- self.color_path(
- "x6-x4-2_path", Scheme.PipeColor.Air
- )
- elif (
- self.valve_states["v5"] == DeviceState.Off
- and self.pump_states["pump2"] == DeviceState.On
- ):
- if self.valve_states["v6"] == DeviceState.Off:
- self.color_path(
- "v5-pump2_path", Scheme.PipeColor.HighVacuum
- )
- elif self.valve_states["v6"] == DeviceState.On:
- if (
- self.valve_states["v7"] == DeviceState.Off
- and self.valve_states["v8"] == DeviceState.Off
- ):
- self.color_path(
- "v5-pump2_path", Scheme.PipeColor.HighVacuum
- )
- self.color_path(
- "pump1-v6_path", Scheme.PipeColor.HighVacuum
- )
- self.color_path(
- "v7-pump1_path", Scheme.PipeColor.HighVacuum
- )
- elif self.valve_states["v9"] == DeviceState.Off:
- self.color_path(
- "v5-pump2_path", Scheme.PipeColor.HighVacuum
- )
- self.color_path(
- "pump1-v6_path", Scheme.PipeColor.HighVacuum
- )
- self.color_path(
- "v7-pump1_path", Scheme.PipeColor.HighVacuum
- )
- self.color_path(
- "cavity-v7_path", Scheme.PipeColor.HighVacuum
- )
- self.color_path(
- "v1-cavity_path", Scheme.PipeColor.HighVacuum
- )
- if self.valve_states["v1"] == DeviceState.On:
- self.color_path(
- "x4-v1_path", Scheme.PipeColor.HighVacuum
- )
- self.color_path(
- "x6-x4-2_path", Scheme.PipeColor.HighVacuum
- )
- elif self.valve_states["x6"] == DeviceState.Off:
- self.color_path("v5-x6_path", Scheme.PipeColor.Air)
- if self.valve_states["v5"] == DeviceState.On:
- self.color_path("v5-pump2_path", Scheme.PipeColor.Air)
- if self.valve_states["v6"] == DeviceState.On:
- self.color_path("pump1-v6_path", Scheme.PipeColor.Air)
- self.color_path("v7-pump1_path", Scheme.PipeColor.Air)
- if (
- self.valve_states["v7"] == DeviceState.On
- or self.valve_states["v8"] == DeviceState.On
- ):
- self.color_path("cavity-v7_path", Scheme.PipeColor.Air)
- self.color_path("v1-cavity_path", Scheme.PipeColor.Air)
- if self.valve_states["v1"] == DeviceState.On:
- self.color_path("x4-v1_path", Scheme.PipeColor.Air)
- self.color_path(
- "x6-x4-2_path", Scheme.PipeColor.Air
- )
- elif self.valve_states["x4"] == DeviceState.On:
- self.color_path("x6-x4-2_path", Scheme.PipeColor.Air)
- if self.valve_states["x6"] == DeviceState.Off:
- self.color_path("x6-tds2_path", Scheme.PipeColor.Air)
- elif (
- self.valve_states["v2"] == DeviceState.Off
- and self.valve_states["v3"] == DeviceState.Off
- and self.valve_states["v4"] == DeviceState.Off
- and self.pump_states["pump2"] == DeviceState.On
- ):
- if (
- self.valve_states["v9"] == DeviceState.Off
- and self.valve_states["v6"] == DeviceState.On
- and (
- self.valve_states["v8"] == DeviceState.On
- or self.valve_states["v7"] == DeviceState.On
- )
- and self.valve_states["v1"] == DeviceState.On
- and self.valve_states["x4"] == DeviceState.On
- and self.valve_states["x6"] == DeviceState.Off
- ):
- for in_valve in ("v2", "v3", "v4"):
- self.color_path(f"{in_valve}_path", Scheme.PipeColor.HighVacuum)
- self.color_path("v2-v3_path", Scheme.PipeColor.HighVacuum)
- self.color_path("v3-v4_path", Scheme.PipeColor.HighVacuum)
- self.color_path("v2-tds1_path", Scheme.PipeColor.HighVacuum)
- self.color_path("tds1-x4_path", Scheme.PipeColor.HighVacuum)
- self.color_path("x6-x4-2_path", Scheme.PipeColor.HighVacuum)
- self.color_path("x6-tds2_path", Scheme.PipeColor.HighVacuum)
- if (
- self.valve_states["v5"] == DeviceState.On
- and self.valve_states["x4"] == DeviceState.Off
- and (
- self.valve_states["v9"] == DeviceState.Off
- or self.valve_states["v6"] == DeviceState.Off
- or (
- self.valve_states["v8"] == DeviceState.Off
- and self.valve_states["v7"] == DeviceState.Off
- )
- )
- ):
- for in_valve in ("v2", "v3", "v4"):
- self.color_path(f"{in_valve}_path", Scheme.PipeColor.HighVacuum)
- self.color_path("v2-v3_path", Scheme.PipeColor.HighVacuum)
- self.color_path("v3-v4_path", Scheme.PipeColor.HighVacuum)
- self.color_path("v2-tds1_path", Scheme.PipeColor.HighVacuum)
- self.color_path("tds1-x4_path", Scheme.PipeColor.HighVacuum)
- self.color_path("x6-x4-1_path", Scheme.PipeColor.HighVacuum)
- self.color_path("v5-pump2_path", Scheme.PipeColor.HighVacuum)
- self.color_path("v5-x6_path", Scheme.PipeColor.HighVacuum)
- if self.valve_states["x6"] == DeviceState.On:
- self.color_path("x6-tds2_path", Scheme.PipeColor.HighVacuum)
- if self.valve_states["v6"] == DeviceState.On:
- self.color_path("pump1-v6_path", Scheme.PipeColor.HighVacuum)
- self.color_path("v7-pump1_path", Scheme.PipeColor.HighVacuum)
- if self.valve_states["v9"] == DeviceState.Off and (
- self.valve_states["v7"] == DeviceState.On
- or self.valve_states["v8"] == DeviceState.On
- ):
- self.color_path("cavity-v7_path", Scheme.PipeColor.HighVacuum)
- self.color_path("v1-cavity_path", Scheme.PipeColor.HighVacuum)
- if self.valve_states["v1"] == DeviceState.On:
- self.color_path("x4-v1_path", Scheme.PipeColor.HighVacuum)
- self.color_path("x6-x4-2_path", Scheme.PipeColor.HighVacuum)
- ""
- if __name__ == "__main__":
- QApplication(sys.argv)
- w: Scheme = Scheme()
- w.locked = False
- w.show()
- QApplication.exec()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement