it seems that the report() function of Operator type lets all other routines finish before it actually reports. this makes it useless in many instances: for example, when reporting progress on baking (I have abandoned the idea of a progress bar and merely want to show a message: 'baking ith map out of n maps'). However, this message would always come at the end. Are there ways to supress this behavior and output a message instantaneously? In Excel VBA, there's DoEvents() built-in function. It lets all processes freeze until the ongoing processes finish
-
1Related https://blender.stackexchange.com/questions/45731/how-to-run-an-external-command-showing-its-progress-without-locking-blender-e https://blender.stackexchange.com/questions/3219/how-to-show-to-the-user-a-progression-in-a-script https://blender.stackexchange.com/questions/47138/how-to-run-a-python-script-without-locking-blender – batFINGER Mar 23 '19 at 04:40
-
@batFINGER thanks looks useful. I'll check it out and update – Serhii Mar 23 '19 at 16:34
1 Answers
probably, such thing as reporting to user interface must be the easiest thing to do in any API but... this is life. anyways, here's what I have found for myself.
Idea in short: so, when blender script runs, Blender does not redraw screen any longer. So I start drawing text into a particular window with blf. Because Blender is not redrawn while the script runs, you actually don't see it. So I force redrawing. And then you can see the text. Don't know how robust that solution is but anyways.
This is the function which starts drawing:
def UI_report_start(message, space_type):
"""
draws specified message, in the specified space_type. space_type is a value in:
['Image Editor',
'Node Editor',
'UV Editor',
'3D View']
returns the draw handler and the space type
for later deletion
"""
# the drawer function
try:
blf
except:
import blf
def draw_message(self, context):
blf.position(0, 15, 30, 0)
blf.size(0, 20, 72)
blf.draw(0, message)
if space_type == 'Image Editor':
handler = bpy.types.SpaceImageEditor.draw_handler_add(draw_message, (None, None), 'WINDOW', 'POST_PIXEL')
return handler, space_type
elif space_type == 'Node Editor':
handler = bpy.types.SpaceNodeEditor.draw_handler_add(draw_message, (None, None), 'WINDOW', 'POST_PIXEL')
return handler, space_type
elif space_type == '3D View':
handler = bpy.types.SpaceView3D.draw_handler_add(draw_message, (None, None), 'WINDOW', 'POST_PIXEL')
return handler, space_type
elif space_type == 'UV Editor':
handler = bpy.types.SpaceUVEditor.draw_handler_add(draw_message, (None, None), 'WINDOW', 'POST_PIXEL')
return handler, space_type
else:
raise Exception('UI_report_start', 'Incorrect Window type specified')
this is the function that stops drawing:
def UI_report_stop(reporter, space_type):
"""
stops drawing the report
the drawing handler and the space type must be input
"""
if space_type == 'Image Editor':
bpy.types.SpaceImageEditor.draw_handler_remove(reporter, 'WINDOW')
elif space_type == 'Node Editor':
bpy.types.SpaceNodeEditor.draw_handler_remove(reporter, 'WINDOW')
elif space_type == '3D View':
bpy.types.SpaceView3D.draw_handler_remove(reporter, 'WINDOW')
elif space_type == 'UV Editor':
bpy.types.SpaceUVEditor.draw_handler_remove(reporter, 'WINDOW')
else:
raise Exception('UI_report_stop', 'Incorrect Window type specified')
this is a hypothetical function taking much time to complete and reporting is embedded into it:
def execute(self, context):
handler, space = UI_report_start("does it have to be THAT difficult?!?!#$", '3D View') # <--- this starts drawing blf but you don't see it yet!
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1) # <--- this is redrawing the screen and you see the message!
# from now on redrawing stops but the message is still 'frozen' in place and you can see it!
for i in range(0, len(bpy.data.images['heavy'].pixels)):
bpy.data.images['heavy'].pixels[i] = random()
UI_report_stop(handler, space) # <-- this removes the message!
return {'FINISHED'}
as you can see, it does not draw the progress bar, only a message but I can live with it.
You can also update the screen more frequently but redrawing and drawing blf takes resources, so do it only once in a while
- 293
- 2
- 13