用python回放FreeCAD建模过程

https://forum.freecad.org/viewtopic.php?t=15529
https://forum.freecad.org/viewtopic.php?p=898244
https://forum.freecad.org/viewtopic.php?p=716143&hilit=QtGui.QTreeWidget#p716143
用deepseek将上述代码拼凑到一起,就形成如下代码:
开始用sleep,结果界面会冻结,不适合,用Qtimer异步就对了。

from PySide.QtCore import Slot, QTimer, QObject
from PySide import QtGui
import FreeCADGui, FreeCAD

class TestClass(QObject):
    def __init__(self):
        super(TestClass, self).__init__()

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.doSomething)

        self.tree = FreeCADGui.getMainWindow().findChildren(QtGui.QTreeWidget)[0]
        self.items = self.get_all_items(self.tree)
        self.current_index = 0

    def get_all_items(self, tree_widget, parent_item=None, parent_columns=0):
        items = []
        if parent_item is None:
            item_count = tree_widget.topLevelItemCount()
        else:
            item_count = parent_item.childCount()
        for i in range(item_count):
            if parent_item is None:
                item = tree_widget.topLevelItem(i)
            else:
                item = parent_item.child(i)
            items.append((item, parent_columns))
            items.extend(self.get_all_items(tree_widget, item, parent_columns + 1))
        return items

    def startDoingSomething(self):
        self.current_index = 0
        if self.items:
            self.timer.start(0)  # 立即触发第一次,由 doSomething 控制后续间隔
        else:
            print("没有可处理的项目")

    @Slot()
    def doSomething(self):
        """逐项处理,只有 column_index == 2 才等待2秒"""
        # 查找下一个需要处理的项目(跳过非层级2的项)
        while self.current_index < len(self.items):
            item, column_index = self.items[self.current_index]

            if column_index == 2:
                # 找到层级2的项目,执行操作
                leading_spaces = "  " * column_index
                print(f"{leading_spaces}{item.text(0)}")
                item.setSelected(1)
                Gui.runCommand('Std_ToggleVisibility', 0)
                item.setSelected(0)
                FreeCAD.ActiveDocument.recompute()

                self.current_index += 1
                # 处理完后等待2秒再继续
                self.timer.start(2000)
                return  # 退出本次回调,等待定时器下次触发

            else:
                # 非层级2的项目,直接跳过(不等待)
                print(f"跳过层级 {column_index}: {item.text(0)}")
                self.current_index += 1
                # 继续循环查找下一个

        # 所有项目处理完毕
        self.timer.stop()
        print("所有项目处理完成")

# 实例化并启动
x = TestClass()
x.startDoingSomething()
作者:秦晓川  创建时间:2026-07-19 12:55
最后编辑:秦晓川  更新时间:2026-07-25 21:05