Just pass align=True when calling the encapsulating layout element like UILayout.row(align=True), UILayout.column(align=True), or UILayout.grid_flow(align=True) to get rid of the padding:
...
layout = self.layout
row = layout.row(align=True)
row.prop(mytool, "my_bool", icon='CAMERA_DATA', text="")
row.prop(mytool, "my_bool", icon='CONSOLE', text="")
row.prop(mytool, "my_bool", icon='ARMATURE_DATA', text="")
...
Demo based on the template from How to create a custom UI?
bl_info = {
"name": "Add-on Template",
"author": "p2or, brockmann",
"version": (0, 0, 3),
"blender": (2, 80, 0),
"location": "3D View > Tools",
"category": "Development"
}
import bpy
from bpy.props import BoolProperty, PointerProperty
from bpy.types import Panel, PropertyGroup
# ------------------------------------------------------------------------
# Scene Properties
# ------------------------------------------------------------------------
class MyProperties(PropertyGroup):
my_bool: BoolProperty(
name="Enable or Disable",
description="A bool property",
default = False
)
# ------------------------------------------------------------------------
# Panel in Object Mode
# ------------------------------------------------------------------------
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"
@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.use_property_split = True
# layout.use_property_decorate = False
row = layout.row(align=True)
row.prop(mytool, "my_bool", icon='CAMERA_DATA', text="")
row.prop(mytool, "my_bool", icon='CONSOLE', text="")
row.prop(mytool, "my_bool", icon='ARMATURE_DATA', text="")
row.prop(mytool, "my_bool", icon='OUTLINER_OB_LIGHT', text="")
row.prop(mytool, "my_bool", icon='BOLD', text="")
grid = layout.grid_flow(columns=5, align=True)
grid.prop(mytool, "my_bool", icon='CAMERA_DATA', text="")
grid.prop(mytool, "my_bool", icon='CONSOLE', text="")
grid.prop(mytool, "my_bool", icon='ARMATURE_DATA', text="")
grid.prop(mytool, "my_bool", icon='BOLD', text="")
col = layout.column(align=True)
col.prop(mytool, "my_bool", icon='CAMERA_DATA', text="")
col.prop(mytool, "my_bool", icon='CONSOLE', text="")
col.prop(mytool, "my_bool", icon='ARMATURE_DATA', text="")
col.prop(mytool, "my_bool", icon='OUTLINER_OB_LIGHT', text="")
col.prop(mytool, "my_bool", icon='BOLD', text="")
# ------------------------------------------------------------------------
# Registration
# ------------------------------------------------------------------------
classes = (
MyProperties,
OBJECT_PT_CustomPanel
)
def register():
from bpy.utils import register_class
for cls in classes:
register_class(cls)
bpy.types.Scene.my_tool = PointerProperty(type=MyProperties)
def unregister():
from bpy.utils import unregister_class
for cls in reversed(classes):
unregister_class(cls)
del bpy.types.Scene.my_tool
if __name__ == "__main__":
register()
Note: If you'd like to use UILayout.use_property_split, make sure you set layout.use_property_decorate to False, otherwise the panel will look like: