How can I create an advanced addon for Blender 2.8x that is displayed in the n menu (right panel of the viewport) with multiple settings. What are the most important GUI scripts, how to add settings, how to access settings between multiple files, how to add icons, how to read the documentation to find lines of code?
-
3$\begingroup$ related or dupe: How to create a custom UI? $\endgroup$– p2orCommented Nov 17, 2019 at 17:07
-
1$\begingroup$ I wanted to make a more in depth answer with multiple scripts snippets. I have edited my question. $\endgroup$– Danyl BekhouchaCommented Nov 17, 2019 at 17:28
1 Answer
Here is how to create addons with an interface in Blender 2.8x. I share here minimalist scripts snippets.
If the addon has multiple files compress it to a .zip.
To enable the addon go in Edit > Preferences..., in the Addon section and type "Minimalist Addon". I suggest you to name your main file __init__.py, it's a convention between every addons. Make sure to use the extension .py for all your files.
To edit your addon you don't need to reimport it each time, you can find it here on Windows: C:\Users\NAME\AppData\Roaming\Blender Foundation\Blender\2.8x\scripts\addons And here on Linux: /home/NAME/.config/blender/2.8x/scripts/addons/ You will need to reopen Blender to see the changes. If the addon doesn't appear it means you have made a mistake somewhere, if it is still visible in the Preferences try to re-enable it to see the error message.
Your addon must be in a folder and not directly in the "addons" folder, otherwise you won't be able to find it in the Preferences.
If you need console (to print message and values by doing print("my message") ) do Window > Toggle System Console on Windows. On Linux download Blender from the website, open the Linux terminal (shortcut Ctrl + Alt + t), type the path to the Blender folder using cd (ls to list the files and folders) then launch Blender by typing ./blender.
Single file addon
This is the most minimalistic addon you can create, it contains a single file, it displays a button that prints "Hello World!" in the console.
__init__.py
bl_info = {
"name" : "Minimalist addon", # The name in the addon search menu
"author" : "Your name",
"description" : "A minimalistic addon",
"blender" : (2, 80, 0), # Lowest version to use
"location" : "View3D",
"category" : "Generic"
}
import bpy
class theInterface_PT_Panel(bpy.types.Panel):
bl_label = "Panel Name"
bl_category = "Tab name"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
def draw(self, context):
layout = self.layout
layout.label(text= "Properties:")
row = layout.row() # Create a new line
row.operator("view3d.print_text", text = "Print text", icon='WORLD_DATA') # Display the operator by calling his idname
class theTools_OT_Operator(bpy.types.Operator): # Create the operator
bl_idname = "view3d.print_text" # idname to display the operator
bl_label = "Simple operator"
bl_description = "Tool description when overing the mouse"
def execute(self, context): # What the operator does
print("Hello World!")
return {'FINISHED'}
classes = (theInterface_PT_Panel, theTools_OT_Operator) # Classes name here
register, unregister = bpy.utils.register_classes_factory(classes)
Multiple files addon
__init__.py (gives the addon informations and gather the files)
The difference here are that the classes are in other files. You must add the lines with the name of your file without .py and class like this: from . File_Name import Classe_Name
bl_info = {
"name" : "Minimalist addon",
"author" : "Your name",
"description" : "A minimalistic addon",
"blender" : (2, 80, 0),
"location" : "View3D",
"category" : "Generic"
}
import bpy
from . Interface_Panel import Interface_PT_Panel
from . Tool_Operator import Tool_OT_Operator
classes = (Interface_PT_Panel, Tool_OT_Operator)
register, unregister = bpy.utils.register_classes_factory(classes)
Tool_Operator.py (what is executed in the addon)
import bpy
class Tool_OT_Operator(bpy.types.Operator):
bl_idname = "view3d.print_text"
bl_label = "Simple operator"
bl_description = "Tool description"
def execute(self, context):
print("Hello World!")
return {'FINISHED'}
Interface_Panel.py (the interface)
import bpy
class Interface_PT_Panel(bpy.types.Panel):
bl_idname = "MenuName_PT_Panel"
bl_label = "Panel Name"
bl_category = "Tab name"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
def draw(self, context):
layout = self.layout
scene = context.scene
layout.label(text= "Properties:")
row = layout.row()
row.operator("view3d.print_text", text = "Print text", icon='WORLD_DATA')
Getting commands
You can get the commands of every tools each time you use one in the Info Window, you can display it by clicking on the Scripting tab at the top of Blender's interface. For example after selecting a mesh, doing right click and selecting Shade Smooth, this command appears:
bpy.ops.object.shade_smooth()
Adding settings and using the values
WIP
Frequent mistakes
- If you operator isn't visible in the interface, check if his class name is unique and do not forget to import it at the classes line at the bottom by writing his name.
- Your addon won't be accessible if it is directly in the scripts folder, you must put it in a sub-folder.
FAQ
What is an operator?
An operator does one or several actions like adding a cube in the 3D view, scaling it then applying a material, all with a single button. The operators are often available by the interface.
What row = layout.row() does?
It creates a new line in the interface, without it your button operators and settings can't be displayed. You can add multiple settings at the same line, however it is recommended to displayed one on each line for a better visiblity.
-
3$\begingroup$ Your naming of the panels and operators doesn't match the
bl_idname
. For exampleTool_OT_Operator
hasbl_idname = "view3d.print_text"
which means it should actually be calledVIEW3D_OT_print_text
. The naming convention is explained here $\endgroup$ Commented Nov 17, 2019 at 17:55 -
$\begingroup$ If I use uppercase OT and remove the dot the script doesn't display the button, maybe I am doing something wrong. $\endgroup$ Commented Nov 17, 2019 at 18:12
-
1$\begingroup$ He didn't mention removing any dot. Don't call single file addons
__init__.py
...foo_bar.py
or if multi file, eg using the folder as a module, have a folderfoo_bar
(generally all lower case) with an__init__.py
Both if in the sys path can be imported withimport foo_bar
See python docs re modules. I would recommend having a register method inpanels.py
in__init__.py
can import the module and callpanels.register()
to register panel classes rather than importing the classes and registering. Notice that a lot of addons useif "bpy" in locals():
toimp
the script .... $\endgroup$ Commented Nov 18, 2019 at 6:41 -
1$\begingroup$ reloadng the script with updated changes, it is not always necessary to restart blender. See also
bpy.ops.script.reload()
The paths and toggle system console are for MS windows users only. This catchall question is pretty broad, many of the sub-questions have answers already, perhaps link to some of them. $\endgroup$ Commented Nov 18, 2019 at 6:46 -
$\begingroup$ I don't understand really well, can you edit my post if you have time, try to keep it as simple to read as possible if you do so, I want to keep it minimalist. Thank you. $\endgroup$ Commented Nov 18, 2019 at 12:41