Here is an example based on this answer. Once it's registered you can press ShiftQ to toggle your BoolProperty. Also notice that tagging the area for a redraw via context.area.tag_redraw()
is requiered after the assignment call in oder to update the Panel properly:
Once it's enabled (or registered) the shortcut is created automatically:

custom-toggle-shortcut.py
bl_info = {
"name": "Add-on Template",
"description": "",
"author": "poor",
"version": (0, 0, 1),
"blender": (2, 70, 0),
"location": "3D View > Tools",
"warning": "", # used for warning icon and text in addons panel
"wiki_url": "",
"tracker_url": "",
"category": "Development"
}
import bpy
# ------------------------------------------------------------------------
# my properties
# ------------------------------------------------------------------------
class MySettings(bpy.types.PropertyGroup):
my_bool = bpy.props.BoolProperty(
name="Enable or Disable",
description="A bool property",
default = False
)
# ------------------------------------------------------------------------
# operators
# ------------------------------------------------------------------------
class ToggleOperator(bpy.types.Operator):
bl_idname = "view3d.toggle_mybool"
bl_label = "Toggle My Bool"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
context.scene.my_tool.my_bool = not context.scene.my_tool.my_bool
context.area.tag_redraw()
return {'FINISHED'}
# ------------------------------------------------------------------------
# my tool in objectmode
# ------------------------------------------------------------------------
class OBJECT_PT_my_panel(bpy.types.Panel):
bl_idname = "OBJECT_PT_my_panel"
bl_label = "My Panel"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_context = "objectmode"
@classmethod
def poll(self,context):
return context.object is not None
def draw(self, context):
layout = self.layout
scene = context.scene
mytool = scene.my_tool
layout.prop(mytool, "my_bool")
# ------------------------------------------------------------------------
# register and unregister
# ------------------------------------------------------------------------
addon_keymaps = []
def register():
bpy.utils.register_module(__name__)
bpy.types.Scene.my_tool = bpy.props.PointerProperty(type=MySettings)
# handle the keymap
wm = bpy.context.window_manager
kc = wm.keyconfigs.addon
if kc:
km = wm.keyconfigs.addon.keymaps.new(name='3D View', space_type='VIEW_3D')
kmi = km.keymap_items.new(ToggleOperator.bl_idname, type='Q', value='PRESS', shift=True)
addon_keymaps.append((km, kmi))
def unregister():
for km, kmi in addon_keymaps:
km.keymap_items.remove(kmi)
addon_keymaps.clear()
bpy.utils.unregister_module(__name__)
del bpy.types.Scene.my_tool
if __name__ == "__main__":
register()
Gist: https://gist.github.com/p2or/8a37617c4565e4ff143b736a0e4a1660
Alternatively using an update method
Rather than create a new operator use the wm.context_toggle
operator, and set up an update method on the property that will redraw the area when run. If the panel is in same area as key press then would only need update=prop_update
def prop_update(self, context):
context.area.tag_redraw()
return None
In example below area_ui_update('VIEW_3D')
returns an update method where if area.type == 'VIEW_3D'
in screen.areas that area will redraw. Useful when your panel is in an area other than context.area eg if your panel was in 'PROPERTIES' you would area_ui_update('PROPERTIES')
import bpy
def area_ui_update(type):
''' tag redraw on areas of type '''
def ui_update(self, context):
areas = [a for a in screen.areas if a.type == type]
for a in areas:
area.tag_redraw()
return None
return ui_update
class MySettings(bpy.types.PropertyGroup):
my_bool = bpy.props.BoolProperty(
name="Enable or Disable",
description="A bool property",
default = False,
update=area_ui_update('VIEW_3D')
)
# ------------------------------------------------------------------------
# my tool in objectmode
# ------------------------------------------------------------------------
class OBJECT_PT_my_panel(bpy.types.Panel):
bl_idname = "OBJECT_PT_my_panel"
bl_label = "My Panel"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_context = "objectmode"
@classmethod
def poll(self,context):
return context.object is not None
def draw(self, context):
layout = self.layout
scene = context.scene
mytool = scene.my_tool
layout.prop(mytool, "my_bool")
# ------------------------------------------------------------------------
# register and unregister
# ------------------------------------------------------------------------
addon_keymaps = []
# register
def register():
bpy.utils.register_module(__name__)
bpy.types.Scene.my_tool = bpy.props.PointerProperty(type=MySettings)
# handle the keymap
wm = bpy.context.window_manager
kc = wm.keyconfigs.addon
if kc:
km = wm.keyconfigs.addon.keymaps.new(name='3D View', space_type='VIEW_3D')
kmi = km.keymap_items.new("wm.context_toggle", type='Q', value='PRESS', shift=True)
kmi.properties.data_path = "scene.my_tool.my_bool"
addon_keymaps.append((km, kmi))
# unregister
def unregister():
for km, kmi in addon_keymaps:
km.keymap_items.remove(kmi)
addon_keymaps.clear()
bpy.utils.unregister_module(__name__)
del bpy.types.Scene.my_tool
if __name__ == "__main__":
register()
window_ manager.deselect_bool
WindowManager
is the class ofcontext.window_manager
Look in system console for error messages. $\endgroup$ – batFINGER Jul 23 '16 at 16:48