奇怪的写法

发布时间 2023-10-11 14:01:37作者: 方头狮

一种整合的PYQT写法 ,自己瞎写的

import sys
from PySide6 import QtCore as qc
from PySide6 import QtWidgets as qw
from PySide6 import QtGui as qg
from typing import Callable


class sig:
    def __init__(self, a: type) -> None:
        self._fns: list[Callable[[a], None]] = []

    def connect(self, fn):
        if fn not in self._fns:
            self._fns.append(fn)

    def emit(self, *args, **kw):
        for i in self._fns:
            try:
                i(*args, **kw)
            except Exception as e:
                print(e)


class line_editer:
    def __init__(self, a=None) -> None:
        if a is None:
            self.v_type = str
        elif a is int or isinstance(a, int):
            self.v_type = int
        elif a is float or isinstance(a, float):
            self.v_type = float
        elif a is str or isinstance(a, float):
            self.v_type = str
        else:
            self.v_type = type(a)
        self.sg = sig(self.v_type)

    def setup(
        self,
        mark: str,
        wg: qw.QWidget = None,
        sg: qc.SignalInstance = None,
        set_mthd=None,
        read_mthd=None,
        add_mthd=None,
    ) -> "line_editer":
        if mark is None:
            self.mark = ""
        else:
            self.mark = str(mark)
        if wg is None:
            self._wg = qw.QLineEdit(self.mark)
            self._wg_sg = self._wg.textChanged
        else:
            self._wg = wg
            self._wg_sg = sg

        self.add_mthd = add_mthd
        if add_mthd is not None:
            add_mthd(self._wg, self.mark)
        self.set_mthd = set_mthd

        self.read_mthd = read_mthd

        if isinstance(self._wg_sg, qc.SignalInstance):
            self._wg_sg.connect(self._read)
        elif callable(self._wg_sg):
            self._wg_sg(self._read)
        return self

    @property
    def v(self):
        if not hasattr(self, "_v"):
            raise ValueError("不能在赋值前调用 v")
        return self._v

    @v.setter
    def v(self, vv):
        #这个赋值会触发重写UI上的内容
        if not hasattr(self, "_wg"):
            raise ValueError(("不能在setup 前赋值 v"))
        if hasattr(self, "_v") and vv == self._v:
            pass
        else:
            self._v = vv
            self.sg.emit()
            if self.set_mthd is None:
                if hasattr(self._wg, "setText"):
                    self._wg.setText(str(self._v))
            else:
                self.set_mthd(self._v)

    def _v2(self, vv):
        #这个赋值 不会  触发重写UI上的内容
        self._v = vv
        self.sg.emit()

    def v_set(self, vv):
        self.v = vv
        return self

    def _read(self):
        if self.read_mthd is None:
            if hasattr(self._wg, "text"):
                if self.v_type is str:
                    try:
                        self._v2(self._wg.text())
                    except:
                        pass
                elif self.v_type is float:
                    try:
                        self._v2(float(self._wg.text()))
                    except:
                        pass

                elif self.v_type is int:
                    try:
                        self._v2(int(self._wg.text()))
                    except:
                        pass
                else:
                    try:
                        self._v2(self.v_type(self._wg.text()))
                    except:
                        raise TypeError(f"不支持的类型转换 {self.v_type}")

        else:
            self.v = self.read_mthd()

    def connect(self, cb):
        self.sg.connect(cb)
        return self


class mw(qw.QDialog):
    def __init__(self) -> None:
        super().__init__()
        self.ly1 = qw.QFormLayout()
        self.setLayout(self.ly1)

        self.le_e1 = line_editer(float).setup("a1", add_mthd=self.add_wg).v_set(0.1)
        self.le_e2 = line_editer(float).setup("a2", add_mthd=self.add_wg).v_set(0.3)
        self.le_e3 = line_editer(float).setup("a3", add_mthd=self.add_wg).v_set(0.5)
        self.le_e4 = line_editer(float).setup("a1+a2+a3", add_mthd=self.add_wg).v_set(0.9)

        self.add_func(self.calc_1, [self.le_e1, self.le_e2, self.le_e3], y=self.le_e4)

        self.resize(300, 300)

    def add_wg(self, wg:qw.QWidget, mk:str):
        self.ly1.addRow(mk,wg)

    def add_func(self, fn, xs: list[line_editer], y: line_editer):
        def _fn():
            s = [i.v for i in xs]
            y.v = fn(*s)

        for i in xs:
            i.sg.connect(_fn)

    def calc_1(self, a, b, c):
        return a + b + c


def main():
    app = qw.QApplication()
    mm = mw()
    mm.show()
    app.exec()
    exit()


if __name__ == "__main__":
    main()