如何正确注册和取消注册“bpy.app.timers”。搅拌机中的功能

问题描述 投票:0回答:1

bpy.app.timers.register(my_func)
未正确注册

我们在尝试时遇到错误

bpy.app.timers.unregister(my_func)

    bpy.app.timers.unregister(clock)
ValueError: Error: function is not registered

我想运行计时器来更新view3d

ba_props.py

class BastromProps(PropertyGroup):
    ...
    clock_interval: IntProperty(
        name="",
        description="update clock every x seconds",
        default=1,
    )

def register():
    bpy.utils.register_class(BastromProps)
    bpy.types.Scene.bapp = PointerProperty(type=BastromProps)
    ...

ba_ui.py

class EVENT_PT_two(Panel):
    bl_idname = "EVENT_PT_one"
    ...

    def draw(self, context):
        layout = self.layout
        bapp = context.scene.bapp

        if bapp.run_clock_1_:
            clock_icon = "PREVIEW_RANGE"
        else:
            clock_icon = "RECOVER_LAST"

        split = layout.split(factor=0.6, align=True)
        ...
        split.operator("event.two_clock", text="", icon=clock_icon)

ba_ops.py

class EVENT_OT_one_clock(Operator):
    # event one 'run clock' button was pressed

    def execute(self, context):
        bapp = bpy.data.scenes["zodiac"].bapp

        # update chart every x seconds
        def update_interval():
            # get local / computer utc timezone-aware datetime
            local_utc_now = datetime.utcnow().replace(tzinfo=zi("UTC"))
            ...
            return bapp.clock_interval

        # toggle 'run clock' mode
        if bapp.run_clock_1_:
            bpy.app.timers.register(update_interval)
            bapp.run_clock_1_ = False
        else:
            bpy.app.timers.unregister(update_interval)
            bapp.run_clock_1_ = True

        if bpy.app.timers.is_registered(update_interval):
            print(
                f"event.one_clock: timers.is_registered: {bpy.app.timers.is_registered}"
            )
            ...

           return {"FINISHED"}

上面的代码给出错误:

    bpy.app.timers.unregister(update_interval)
ValueError: Error: function is not registered

我从网上尝试了一些结果,即:

update_interval(self)
移到
execute(...)
函数之外,然后:

clock = self.update_interval()

if bapp.run_clock_1_:
    bpy.app.timers.register(clock)
    bapp.run_clock_1_ = False
else:
    bpy.app.timers.unregister(clock)
    bapp.run_clock_1_ = True

仍然报错

我们如何修复代码才能正常运行?

(添加更多详细信息,否则我无法发布问题)

python blender
1个回答
0
投票

是的,你是对的,你必须将

update_interval
函数移到
execute
之外。

如果

update_interval
定义在
execute
内部,则每次运行操作符时都会创建
update_interval
的新实例。因此,当您尝试调用
bpy.app.timers.unregister(update_interval)
时,它总是会失败,因为它是不同的实例。


然后,如果您想在

clock_interval
函数内部使用
update_interval
属性,您可以:

  1. 从函数中的场景中获取
def update_interval():
    interval = bpy.context.scene.bapp.clock_interval
    <...update logic...>
    return interval
  1. 将其从操作符传递到函数中
import functools

update_func = None

def update_interval(interval):
    <...update logic...>
    return interval


class EVENT_OT_one_clock(Operator):
    def execute(self, context):
        bapp = bpy.context.scene.bapp

        global update_func

        if bapp.run_clock_1_:
            # store function in a variable so it can be unregistered later
            update_func = functools.partial(update_interval, bapp.clock_interval)
            bpy.app.timers.register(update_func)

        <...other operator code...>

或者,如果您希望

update_interval
函数成为类的一部分,如您的示例所示:

时钟 = self.update_interval()

您需要使用

functools.partial
才能正确注册:

self.update_func = functools.partial(self.update_interval)
bpy.app.timers.register(self.update_func)

您还应该确保在尝试注销计时器之前始终检查计时器是否已注册,以便可以处理错误:

if bpy.app.timers.is_registered(update_func):
    bpy.app.timers.unregister(update_func)
else:
    print("error")

此外,要更改场景属性,您需要使用原始对象而不是副本。在您的代码中,

run_clock_1_
将始终为 false。

# this won't work
bapp = bpy.context.scene.bapp
bapp.run_clock_1_ = False
# this works
bpy.context.scene.bapp.run_clock_1_ = False
© www.soinside.com 2019 - 2024. All rights reserved.