有意思的是把数据model独立出来的写法
- txt_syc可以绑定多个lineedit,其中一个文字发生更改后,其它的会同时改动。
- txt_syc可以connect信号接收器,当自己的值发生改变后,接收器会执行一此操作。
- txt_syc可以更改自己的值,相当的ui和函数可以自动触发。
![]()
from PySide6.QtWidgets import (
QApplication,
QGroupBox,
QFormLayout,
QLineEdit,
)
from PySide6.QtCore import Signal
import qdarktheme
from typing import Any, Callable, ClassVar, Protocol, TypeVar, runtime_checkable
T = TypeVar("T")
# region model
@runtime_checkable
class txt_holder(Protocol):
textChanged: ClassVar[Signal]
def setText(self, s: str): ...
def text(self) -> str: ...
class txt_syc:
"""文字同步修改器"""
def __init__(self, s: str = "", name=""):
self._value: str = s
self._old_value: str = s
self.name = name
self._ents: list[txt_holder] = []
self._fns: list[Callable[[str], Any]] = []
@property
def txt(self):
return self._value
@txt.setter
def txt(self, v: str):
vv = str(v)
if vv != self._old_value:
self._old_value = self._value
self._value = vv
for fn in self._fns:
try:
fn(self._value)
except Exception as e:
print(e)
for i in self._ents:
if i.text() != vv:
i.setText(vv)
# 重载了运算符 +
def __radd__(self, tt: T) -> T:
if isinstance(tt, txt_holder):
self._ents.append(tt)
tt.textChanged.connect(self.set_text) # type: ignore
tt.setText(self.txt)
return tt
else:
raise NotImplemented
def set_text(self, v: str):
self.txt = v
def connect(self, fn: Callable[[str], Any]):
self._fns.append(fn)
# 重载了运算符 >>
def __rshift__(self, fn: Callable[[str], Any]):
self.connect(fn)
return self
# endregion
class spring:
"""弹簧K值和压缩量计算"""
def __init__(self) -> None:
self.g = txt_syc("79800", "G N/mm\u00b2") >> self.on_change_g1 # 重载了运算符 >>
self.d1 = txt_syc("3", "线径 mm") >> self.on_change_g1
self.d2 = txt_syc("15", "中径 mm") >> self.on_change_g1
self.n = txt_syc("2", "圈数 ") >> self.on_change_g1
self.k = txt_syc("119.7", "K N/mm")
self.f = txt_syc("210", "F N ") >> self.on_change_g1
self.ll = txt_syc("1.75", "压缩行程 mm")
self.edit = [self.g, self.d1, self.d2, self.n, self.f]
self.readonly = [self.k, self.ll]
def on_change_g1(self, s):
try:
g = float(self.g.txt)
d2 = float(self.d2.txt)
d1 = float(self.d1.txt)
n = float(self.n.txt)
f = float(self.f.txt)
k = g / 8 * d1**4 / d2**3 / n
l1 = f / k
print(g, d1, d2, n, f, k, l1)
self.k.txt = f"{k:.4f}"
self.ll.txt = f"{l1:.4f}"
except:
pass
class gp(QGroupBox):
def __init__(self):
super().__init__()
self.setStyleSheet(
"""
[level="groupbox"] {border:2px solid #FF7E72;margin-top:5px;margin:20px;}
[level="groupbox"]::title{subcontrol-origin:margin; padding:0.3px;margin-top:10px;}
"""
)
self.setTitle("弹簧K值")
self.setProperty("level", "groupbox")
# 初始化模型
self.ss = spring()
# 布局
ly = QFormLayout()
self.setLayout(ly)
# 添加行
for i in self.ss.edit:
ly.addRow(i.name, QLineEdit() + i) # 重载了运算符
for i in self.ss.readonly:
ly.addRow(i.name, g := QLineEdit() + i)# 重载了运算符
g.setReadOnly(True)
if __name__ == "__main__":
app = QApplication()
qdarktheme.setup_theme("light")
window = gp()
window.show()
app.exec()