1
$\begingroup$

I wrote the following code.

This is just the code to get the value from the textbox and print it.

But this doesn't work.

When I run this code, blender crashes.

What's wrong with this code?

import bpy

bl_info = {
    "name": "test addon",
    "author": "taichi suzuki",
    "version": (1, 0),
    "blender": (2, 80, 0),
    "location": "3DView",
    "description": "test addon",
    "warning": "",
    "support": "COMMUNITY",
    "wiki_url": "",
    "tracker_url": "",
    "category": "test"
}

class QueryProps_query(bpy.types.PropertyGroup):
    query: bpy.props.StringProperty(default="aaa")

class TestAddon_PT_Panel(bpy.types.Panel):
    blidname = "TestAddon_PT_Panel"
    bl_label = "TestAddon Panel"
    bl_category = "TestAddon"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    
    def draw(self,context):
        props_query = bpy.context.scene.QueryProps_query
        layout = self.layout
        
        row = layout.row()
        row.label(text="test textbox")
        row.prop(props_query, "query", text="")
        
        vis_box = layout.box()
        
        vis_box.operator(TestAddon_OT_Operator.bl_idname,text ='modal start')

class TestAddon_OT_Operator(bpy.types.Operator):
    bl_idname = "wm.modal_testaddon_operator"
    bl_label = "Modal testaddon Operator"
    _timer = None
        
    def __init__(self):
        self.test = None

    def modal(self, context, event):
        if event.type in {'ESC'}:
            self.cancel(context)
            return{'CANCELLED'}

        if event.type=='TIMER':
            print(self.query)

        return{'PASS_THROUGH'}

    def execute(self, context):
        wm = context.window_manager

        if TestAddon_OT_Operator._timer is None:
            TestAddon_OT_Operator._timer = wm.event_timer_add(1.00/60.00, window=context.window)
            wm.modal_handler_add(self)
            print(self.query)
        
        return {'RUNNING_MODAL'}

    def cancel(self, context):
        wm = context.window_manager
        wm.event_timer_remove(self._timer)
        TestAddon_OT_Operator._timer = None

classes = (QueryProps_query,TestAddon_PT_Panel,TestAddon_OT_Operator)

def register():
    from bpy.utils import register_class
    for cls in classes:
        register_class(cls)
        
    bpy.types.Scene.QueryProps_query = bpy.props.PointerProperty(type=QueryProps_query)
    
def unregister():
    from bpy.utils import unregister_class
    for cls in classes:
        unregister_class(cls)
        
    del(bpy.types.Scene.QueryProps_query)

if __name__ == "__main__":
    register()
$\endgroup$
2
$\begingroup$

You are trying to access a member named query of your operator on lines 53 et 63, but it doesn't exist. Instead you want to access the property group you created in your register method : context.scene.QueryProps_query.query.

Side note : Don't use bpy.context in an operator, because it is not always the right context. (L.28) Use the provided context parameter instead.

import bpy

bl_info = {
    "name": "test addon",
    "author": "taichi suzuki",
    "version": (1, 0),
    "blender": (2, 80, 0),
    "location": "3DView",
    "description": "test addon",
    "warning": "",
    "support": "COMMUNITY",
    "wiki_url": "",
    "tracker_url": "",
    "category": "test"
}

class QueryProps_query(bpy.types.PropertyGroup):
    query: bpy.props.StringProperty(default="aaa")

class TestAddon_PT_Panel(bpy.types.Panel):
    blidname = "TestAddon_PT_Panel"
    bl_label = "TestAddon Panel"
    bl_category = "TestAddon"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    
    def draw(self, context):
        props_query = context.scene.QueryProps_query
        layout = self.layout
        
        row = layout.row()
        row.label(text="test textbox")
        row.prop(props_query, "query", text="")
        
        vis_box = layout.box()
        
        vis_box.operator(TestAddon_OT_Operator.bl_idname,text ='modal start')

class TestAddon_OT_Operator(bpy.types.Operator):
    bl_idname = "wm.modal_testaddon_operator"
    bl_label = "Modal testaddon Operator"
    _timer = None
        
    def __init__(self):
        self.test = None

    def modal(self, context, event):
        if event.type in {'ESC'}:
            self.cancel(context)
            return{'CANCELLED'}

        if event.type=='TIMER':
            print(context.scene.QueryProps_query.query)

        return{'PASS_THROUGH'}

    def execute(self, context):
        wm = context.window_manager

        if TestAddon_OT_Operator._timer is None:
            TestAddon_OT_Operator._timer = wm.event_timer_add(1.00/60.00, window=context.window)
            wm.modal_handler_add(self)
            print(context.scene.QueryProps_query.query)
        
        return {'RUNNING_MODAL'}

    def cancel(self, context):
        wm = context.window_manager
        wm.event_timer_remove(self._timer)
        TestAddon_OT_Operator._timer = None

classes = (QueryProps_query,TestAddon_PT_Panel,TestAddon_OT_Operator)

def register():
    from bpy.utils import register_class
    for cls in classes:
        register_class(cls)
        
    bpy.types.Scene.QueryProps_query = bpy.props.PointerProperty(type=QueryProps_query)
    
def unregister():
    from bpy.utils import unregister_class
    for cls in classes:
        unregister_class(cls)
        
    del(bpy.types.Scene.QueryProps_query)

if __name__ == "__main__":
    register()
$\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.