analitics

Pages

Thursday, March 12, 2026

Python Qt6 : schemdraw - 001.

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())

News : Major new features of the 3.15 series, compared to 3.14

Python 3.15 is still in development. This release, 3.15.0a7, is the seventh of eight planned alpha releases.
...The JIT compiler has been significantly upgraded, with 3-4% geometric mean performance improvement on x86-64 Linux over the standard interpreter, and 7-8% speedup on AArch64 macOS over the tail-calling interpreter