Today, simple example with PyQt6 and schemdraw :

# -*- coding: utf-8 -*-
import sys
import schemdraw
import schemdraw.elements as elm
from PyQt6.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QVBoxLayout, QScrollArea
from PyQt6.QtGui import QPixmap
def draw_bistabil_grid(state):
"""
state = 0 -> switch spre R3, LED1 aprins
state = 1 -> switch spre R4, LED2 aprins
"""
with schemdraw.Drawing(file='bistabil_grid.png', show=False) as d:
d.config(unit=2.0)
# Y COORDINATES
y_led = 0.0
y_r1 = -2.0
y_rfb = -4.0
y_swT = -7.0
y_gnd = -10.0
# X COORDINATES
x_left = -6.0
x_right = 6.0
x_t1 = -3.0
x_t2 = 3.0
x_sw = 0.0
# COLORS
col_T1 = 'green'
col_T2 = 'orange'
# LED-uri colorate în funcție de state
led1_color = 'red' if state == 0 else 'gray'
led2_color = 'red' if state == 1 else 'gray'
# 1. LED1 and LED2
led1 = d.add(elm.LED().down().at((x_left, y_led)).color(led1_color).label('LED1'))
led2 = d.add(elm.LED().down().at((x_right, y_led)).color(led2_color).label('LED2'))
# 2. R1 and R2
r1 = d.add(elm.Resistor().down().at(led1.end).label('R1'))
r2 = d.add(elm.Resistor().down().at(led2.end).label('R2'))
n_r1 = d.add(elm.Dot().at(r1.end))
n_r2 = d.add(elm.Dot().at(r2.end))
# 3. R3 and R4 (feedback)
d.add(elm.Line().at(n_r1.center).to((x_t1, y_rfb)))
r3 = d.add(elm.Resistor().right().at((x_t1, y_rfb)).label('R3'))
n_r3 = d.add(elm.Dot().at(r3.end))
d.add(elm.Line().at(n_r2.center).to((x_t2, y_rfb)))
r4 = d.add(elm.Resistor().left().at((x_t2, y_rfb)).label('R4'))
n_r4 = d.add(elm.Dot().at(r4.end))
# 4. Transistors
t1 = d.add(
elm.BjtNpn()
.left()
.flip()
.at((x_t1, y_swT))
.anchor('base')
.label('T1')
)
t2 = d.add(
elm.BjtNpn()
.right()
.at((x_t2, y_swT))
.anchor('base')
.label('T2')
)
# BASE CONNECTIONS
d.add(elm.Line().at(n_r4.center).to(t1.base).color(col_T1))
d.add(elm.Line().at(n_r3.center).to(t2.base).color(col_T2))
# COLLECTOR CONNECTIONS
d.add(elm.Line().at(t1.collector).to(n_r1.center).color(col_T1))
d.add(elm.Line().at(t2.collector).to(n_r2.center).color(col_T2))
# -------------------------------
# 5. SWITCH SPDT DESENAT MANUAL
# -------------------------------
# Punctele a, b, c
a = d.add(elm.Dot().at((x_sw - 1, y_swT)))
b = d.add(elm.Dot().at((x_sw, y_swT)))
c = d.add(elm.Dot().at((x_sw + 1, y_swT)))
# Linii FIXE către R3 și R4
d.add(elm.Line().at(n_r3.center).to(a.center))
d.add(elm.Line().at(n_r4.center).to(c.center))
# Linia FIXĂ către GND
d.add(elm.Line().at(b.center).to((b.center[0], y_gnd)))
# Brațul mobil (UNICA linie care se mișcă)
if state == 0:
d.add(elm.Line().at(b.center).to(a.center))
else:
d.add(elm.Line().at(b.center).to(c.center))
# 6. Ground bus
d.add(
elm.Line()
.at((x_left - 2, y_gnd))
.to((x_right + 2, y_gnd))
.label('0V', loc='bottom')
)
d.add(elm.Ground().at((x_left - 2, y_gnd)))
# EMITTERS TO GND
d.add(elm.Line().at(t1.emitter).to((t1.emitter[0], y_gnd)).color(col_T1))
d.add(elm.Line().at(t2.emitter).to((t2.emitter[0], y_gnd)).color(col_T2))
class BistabilGUI(QWidget):
def __init__(self):
super().__init__()
self.state = 0
self.setWindowTitle("Bistabil Animat – Schema completă")
# Scroll area
self.scroll = QScrollArea()
self.label = QLabel()
self.scroll.setWidget(self.label)
self.scroll.setWidgetResizable(True)
self.button = QPushButton("Comută switch-ul")
self.button.clicked.connect(self.toggle_switch)
layout = QVBoxLayout()
layout.addWidget(self.scroll)
layout.addWidget(self.button)
self.setLayout(layout)
self.update_image()
def toggle_switch(self):
self.state = 1 - self.state
self.update_image()
def update_image(self):
draw_bistabil_grid(self.state)
pix = QPixmap("bistabil_grid.png")
self.label.setPixmap(pix)
if __name__ == "__main__":
app = QApplication(sys.argv)
gui = BistabilGUI()
gui.show()
sys.exit(app.exec())


