I have a panel in 3D_View that shows the current file and allows the selection of a new file. When the file is selected, the panel needs to redraw. How do I force a redraw?

In Operator.py file

class OT_TestOpenFilebrowser(Operator, ImportHelper): 
    bl_idname = "file.open_filebrowser" 
    bl_label = "Open the file browser (yay)" 
    filter_glob: StringProperty( default='*.xml', options={'HIDDEN'} )
    def execute(self, context): 
        if not 'PMTfileName' in globals():
            global PMTfileName
            PMTfileName = "None2"        
            self.report({'INFO'}, PMTfileName+ " created in op") 
        PMTfileName, extension = os.path.splitext(self.filepath)
        head_tail = os.path.split(self.filepath) 
        PMTfileName = head_tail[1]
        self.report({'INFO'}, PMTfileName)
        self.report({'INFO'}, extension)
        self.report({'INFO'}, self.filepath)
        self.__class__.run += 1
        """Do something with the selected file(s).""" 
        return {'FINISHED'}

If Panel file:

class PMT_PT_Pannel(Panel):
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_label = "PMT Builder"
    bl_category = "21Geo Builder"

    def draw(self, context):
        global PMTfileName
        layout = self.layout

        #2 Columns with Buttons
        box = layout.box()
        box.label(text="Open File: "+PMTfileName) 
        row = layout.row()
        row2 = layout.row()

        col3 = row.column()
        col3.operator("file.open_filebrowser", text="Select File" )

        col = row2.column()
        col.operator("object.apply_all_mods", text="Apply all")

        col2 = row2.column()
        col2.operator("export.some_data", text="Export")

2 Answers 2


I suggest start here: How to create a custom UI?

Blender will take care of (re-)drawing the layout properly without doing anything if you add a dedicated StringProperty for your filepath to the Scene, Object or whatever makes sense in your case eg. bpy.types.Scene.my_path = StringProperty(name="My Path") and assign self.filepath attribute from the ImportHelper class to your path property:

enter image description here

Code example based on the famous Operator File Import template that comes with Blender:

import bpy
import os

# ImportHelper is a helper class, defines filename and
# invoke() function which calls the file selector.
from bpy_extras.io_utils import ImportHelper
from bpy.props import StringProperty, BoolProperty, EnumProperty
from bpy.types import Operator, Panel

class ImportSomeData(Operator, ImportHelper):
    """This appears in the tooltip of the operator and in the generated docs"""
    bl_idname = "import_test.some_data"  # important since its how bpy.ops.import_test.some_data is constructed
    bl_label = "Import XML Data"

    # ImportHelper mixin class uses this
    filename_ext = ".xml"

    filter_glob: StringProperty(
        maxlen=255,  # Max internal buffer length, longer would be clamped.

    # List of operator properties, the attributes will be assigned
    # to the class instance from the operator settings before calling.
    use_setting: BoolProperty(
        name="Example Boolean",
        description="Example Tooltip",

    def execute(self, context):
        folder, file = os.path.split(self.filepath)
        context.scene.my_path = self.filepath
        print (folder, file)
        return {'FINISHED'}

class OBJECT_PT_CustomPanel(Panel):
    bl_label = "My Panel"
    bl_idname = "OBJECT_PT_custom_panel"
    bl_space_type = "VIEW_3D"   
    bl_region_type = "UI"
    bl_category = "Tools"
    bl_context = "objectmode"
    def poll(self,context):
        return context.object is not None
    def draw(self, context):
        layout = self.layout
        scene = context.scene
        layout.prop(scene, "my_path", text="File")
def register():
    bpy.types.Scene.my_path = StringProperty(name="My Path")

def unregister():
    del bpy.types.Scene.my_path

if __name__ == "__main__":

    # test call
  • $\begingroup$ When I do this I get this error: AttributeError: Writing to ID classes in this context is not allowed: Scene, Scene datablock, error setting Scene.my_path $\endgroup$
    – doby
    Commented Feb 20, 2021 at 2:54
  • $\begingroup$ Are you trying to re-write the property (assigning something to my_path) within the panel class...? If so, please study my demo code. OR What part of my demo code do you have changed to get this error? Tested on 2.91 but I don't see any reason why it should not work for versions pre 2.91 @doby Can not help much based on your comment, I suggest edit your question and add more detail about what you're doing exactly. $\endgroup$
    – brockmann
    Commented Feb 20, 2021 at 8:21
  • $\begingroup$ I got it working. I failed to see that you initialized the variable in the execute. It worked once I did that. Thank you! $\endgroup$
    – doby
    Commented Feb 21, 2021 at 16:15


works in v3.3.

More generally, you can figure out the area and region index you need by typing / iterating though

bpy.data.screens[<screen/tab name>].areas[x].type

bpy.data.screens[<screen/tab name>].areas[x].regions[y].type

in the interactive console since this displays the name of that area/region as they aren't keyed like the screens are.


You must log in to answer this question.

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