2
$\begingroup$

In my code, some data items are created, then a new window is opened via bpy.ops.wm.window_new. The user can then do a number of things within this window, manipulating the data just created. I have a function that is supposed to run when the user is done with the window and wants to exit. I've registered an operator that runs this function and closes the window, but what if the user just clicks the red 'X' button in the corner to close the window without calling my operator? How do I make my function run when the user closes the window?

import bpy

a = piece_of_data
b = another_piece_of_data

bpy.ops.wm.window_new()

def on_close():
    do_stuff()
    bpy.ops.wm.window_close()
    print ('window was closed')

class WM_OT_close_my_window(bpy.types.Operator):
    bl_idname = 'wm.close_my_window'
    bl_label = 'Close my window'

    def execute(self, context):
        on_close()
        return {'FINISHED'}

def draw_item(self, context):
    self.layout.operator(WM_OT_close_my_window.bl_idname, icon='CANCEL')

def register():
    bpy.utils.register_class(WM_OT_close_my_window)
    bpy.types.VIEW3D_HT_header.append(draw_item)

def unregister():
    bpy.types.VIEW3D_HT_header.remove(draw_item)
    bpy.utils.unregister_class(WM_OT_close_my_window)

if __name__ == '__main__':
    register()
$\endgroup$
1
  • $\begingroup$ You might want to look into msgbus as a solution, or possibly a calback on depsgraph to detect the close event. $\endgroup$ Commented Apr 12, 2022 at 16:54

1 Answer 1

2
$\begingroup$

Use the threading module. It allows you to run while loops concurrently with Blender's usual functioning. You can use a while loop to periodically check if the window's been closed, and if so, exit the while loop and run your on_close() function.

import bpy
import threading
from time import sleep

a = piece_of_data
b = another_piece_of_data

bpy.ops.wm.window_new()
my_window = bpy.data.window_managers[0].windows[-1]

def on_close():
    do_stuff()
    print ('window was closed')

def on_window_close():
    window_open = True
    while window_open:
        sleep(0.25) #Set the value to however often you want to check if the window's been closed
        if my_window not in bpy.data.window_managers[0].windows.values():
            window_open = False
    on_close()

my_thread = threading.Thread(target=on_window_close)
my_thread.start()
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .