1
$\begingroup$

I would simply like to understand how to close the render window after it is finished and ready. The save path is already set, so it does not require manual save.

Right now I use this system to render, and it works well:

bpy.ops.render.render('INVOKE_DEFAULT',animation=False, write_still=True)

I thought adding a simple operator to close the window, I found this in the blender documents:

bpy.ops.render.view_cancel()

But obviously it gives me a context error.

I don't understand what kind of context I have to overwrite to pass the right context, I think the rendering window has its context, but it is really difficult to get to this solution

How to use bpy.ops.render.view_cancel() to close render view?

Edit:

I am trying to reach the right context I think I have succeeded, now I no longer receive the error, but this operator does not seem to close the window, on the contrary, brings it back to the foreground:

for w in bpy.context.window_manager.windows:             
    for area in w.screen.areas:        
        if area.type == 'IMAGE_EDITOR': 
            for rgn in area.regions:
                if rgn.type == 'WINDOW':
                    override = {'window': w, 'screen': w.screen, 'area': area, 'region': rgn,'workspace': w.workspace} 

bpy.ops.render.view_cancel(override)   
$\endgroup$
1
  • $\begingroup$ You should just be able to manually close the render window after it's done. $\endgroup$ – Nate_Sycro27 Jan 19 '20 at 23:41
2
+100
$\begingroup$

The new window has context after op call.

EDIT: Looked into this and remembered it did as expected using a timer. Hence added a timer call in handler to delay the window closing. Have run this numerous times with delay 10 seconds without any crashes. Try with smaller delays.

Worth mentioning the behaviour of render operator depends on User Settings > Interface > Editors > Temporary Windows Render in new window being set.

If it is, the context is switched from old to new window when the operator is invoked.

Another way to get a new window would be to

windows_before = set(context.window_manager.windows[:])
.. operator ...

windows_after = set(context.window_manager.windows[:])

and get the new window via

new_window = (windows_after - windows_before).pop() # if there is a new window

Here in a test script, the render window is cancelled (closed with close operator) 10 seconds after, using a timer, the render complete handler is fired..

This will go astray, prob a core dump because of removed reference to window. if the user manually closes the window. Passing instead some info about the window eg it has one image editor its index in window manager collection would be a way to alleviate this risk. Also might pay to look at context.mode after render call, to see if it reveals anything useful.

Python console test, get its index, test is this the render window?

>>> C.window_manager.windows[:].index(C.window)
0
>>> len(C.window.screen.areas) == 1
True
>>> C.window.screen.areas[0].type == 'IMAGE_EDITOR'
False

Using the window close operator, i believe only requires having a window for context.

import bpy
from time import sleep

context = bpy.context
w = context.window
print(context.window)
bpy.ops.render.render('INVOKE_DEFAULT')
print(context.window, w == context.window)
c = context.copy()


def shut_window():
    bpy.ops.wm.window_close(c)
    return None

def render_complete(scene):
    bpy.app.timers.register(shut_window, first_interval=10)
    #shut_window()
    bpy.app.handlers.render_complete.remove(render_complete)

bpy.app.handlers.render_complete.append(render_complete)
$\endgroup$
3
  • $\begingroup$ Thanks for your interest, there is something wrong, copying and pasting your script, blender 2.81 has a crash without reporting errors $\endgroup$ – Noob Cat Jan 16 '20 at 10:36
  • 1
    $\begingroup$ Yeah is a little dodgy. I'm on 2.8.3 and although this script worked Ok, tried running on a new file get the crash too. Will delete for now and re-post if I find a fix. $\endgroup$ – batFINGER Jan 16 '20 at 10:58
  • $\begingroup$ Thanks for solving this question with another type of operator which is what I needed and didn't know bpy.ops.wm.window_close() is cast gold. I had already tried the timer and it is always better to delay 1 second at least because otherwise you run into errors $\endgroup$ – Noob Cat Jan 20 '20 at 11:59
1
$\begingroup$

I think it refers to going back to the 3d view, you just feel like searching for the 'IMAGE_EDITOR' area and changing it to 'VIEW_3D'.

Example for that:

import bpy

bpy.ops.render.render('INVOKE_DEFAULT',animation=False, write_still=True)

for area in bpy.context.screen.areas:
    if area.type == 'IMAGE_EDITOR':
        area.type = 'VIEW_3D'

I hope it helps you.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.