Pyside刷新界面
pyside刷新界面, 同时不要阻塞用户操作
timer定时器写法
- 要点: timer要么绑在一个持久化的对象上, 要么在main里面(有app.exec和sys.exit的地方, 他是个死循环)
# main中使用timer可以直接用, 不必绑持久对象
timer = QTimer()
timer.timeout.connect(lambda: flexlayout(movnode=movnode, contnode=contnode))
timer.start(1)
# 绑持久化对象的写法
setattr(view, "timer", timer)
# 可以只执行一次的写法
def run_once():
flexlayout(movnode=movnode, contnode=contnode)
timer.stop()
timer.timeout.connect(run_once)
成批计算写法
def flexlayout_progressive(*, update_nodes):
"""分批进行布局计算,每批处理后允许界面更新"""
batch_size = 10 # 每批计算10次
while True: # 死循环, 如果有不收敛的可能性, 这里也可以搞个判断
# 计算一批
for i in range(batch_size):
if 收敛判断():return True # 提前收敛
update_nodes() # 你的更新代码
# 处理界面事件,防止阻塞
QApplication.processEvents()
# 可选:更新界面显示中间结果
upalline(movnode)
# 这里也可以判断性返回, 判断条件: 计算的次数, 持续时间等
return False # 未完全收敛
异步计算
from PySide6.QtCore import QThread, pyqtSignal
class LayoutThread(QThread):
uSig = pyqtSignal()
def run(self):
while not 收敛判断():
update_nodes() # 你的更新代码
self.uSig.emit() # 通知主线程更新界面
self.msleep(16) # 60fps的间隔
# 不用这个, 直接用timer也是可以的,
# 1. 可以判断满足条件就stop
# 2. 可以singleshot
def 递归调用():
if 收敛判断() : return # 完成
update_nodes() #你的更新代码
# 1ms后递归调用自己
QTimer.singleShot(1, lambda: 递归调用())