Closed Lynchon83 closed 5 years ago
Hi there, happy to help. The use case you describe is certainly a worthwhile example of using this updater solution.
For your issue, try the modified code below. Notice how I run the registration of the updater code separately from the others (and also removed the updater files from modulesNames); this is because its registration needs to have the bl_info passed in as an argument(to get the true addon version and name), which normally is not needed for registration code and hence the others can still register fine without it.
Let me know if you still have issues after trying this!
`bl_info = {
"name" : "Lynchon Tools 2.80",
"author" : "Lynchon",
"description" : "",
"version" : (1,0),
"blender" : (2, 80, 0),
"location" : "",
"warning" : "",
"category" : "Generic"
}
import bpy
from . import addon_updater_ops
modulesNames = ['UI','y_up','xml_parse_particles', 'xml_parse_conformHeight', 'metal_compiler','edit_pivot','uv_tube_unwrap','Hidesato Offset Edges','fillet_280']
import sys
import importlib
modulesFullNames = {}
for currentModuleName in modulesNames:
modulesFullNames[currentModuleName] = ('{}.{}'.format(__name__, currentModuleName))
for currentModuleFullName in modulesFullNames.values():
if currentModuleFullName in sys.modules:
importlib.reload(sys.modules[currentModuleFullName])
else:
globals()[currentModuleFullName] = importlib.import_module(currentModuleFullName)
setattr(globals()[currentModuleFullName], 'modulesNames', modulesFullNames)
def register():
# addon updater code and configurations
addon_updater_ops.register(bl_info)
for currentModuleName in modulesFullNames.values():
if currentModuleName in sys.modules:
if hasattr(sys.modules[currentModuleName], 'register'):
sys.modules[currentModuleName].register()
def unregister():
# addon updater unregister
addon_updater_ops.unregister()
for currentModuleName in modulesFullNames.values():
if currentModuleName in sys.modules:
if hasattr(sys.modules[currentModuleName], 'unregister'):
sys.modules[currentModuleName].unregister()`
Thank you very much! That solved my registration problem. But right now I'm having trouble drawing the preferences panel, and I'm quite lost because I already have a preferences panel being drawn from one of my scripts so I don't understand why is not working, I've been following the tutorial but with no success, let me show you how I'm trying to draw the preferences panel from my UI script, maybe you see whats missing.
import bpy
from bpy.props import (StringProperty,
BoolProperty,
IntProperty,
FloatProperty,
EnumProperty,
PointerProperty
)
from bpy.types import (Panel,
Operator,
PropertyGroup
)
from . import addon_updater_ops
class MySettings(PropertyGroup):
path : StringProperty(
name="path",
description="Path to Directory",
default="",
maxlen=1024,
subtype='DIR_PATH')
conform_threshold : FloatProperty(
name="conform_threshold",
description="A float property",
default=0.1,
min=-5,
max=30.0)
invert : BoolProperty(
name="Enable or Disable",
description="A simple bool property",
default = False)
class UI_PT_LynchonPanel(bpy.types.Panel):
"""Las super herramientas de Juan"""
bl_label = "Lynchon Tools"
bl_space_type = 'VIEW_3D'
bl_region_type = "UI"
bl_category = "Lynchon Tools"
def draw(self, context):
layout = self.layout
row = layout.row()
row.operator("object.y_up")
row = layout.row()
row.operator("mesh.simple_edit_pivot")
row = layout.row()
row.operator("uv.tube_uv_unwrap")
split = layout.split()
# First column
col = split.column()
col.operator("mesh.hidesato_offset_edges", text='Offset').geometry_mode='offset'
col = split.column(align=True)
# Second column
col.operator("mesh.hidesato_offset_edges", text='Offset Extrude').geometry_mode='extrude'
col = split.column(align=True)
col.operator("mesh.hidesato_offset_edges_profile", text='Offset with Profile')
row = layout.row()
row.operator("curve.fillet")
# split = layout.split()
# # First column
# col = split.column()
# col.operator("texture.metal_compiler")
# # Second column
# scn = context.scene
# mytool = scn.my_tool
# col = split.column(align=True)
# col.prop(mytool, 'invert' ,text = "Invert")
class UI_PT_LynchonMMCPanel(bpy.types.Panel):
"""Las super herramientas de Juan"""
bl_label = "MMC Tools"
bl_space_type = 'VIEW_3D'
bl_region_type = "UI"
bl_category = "Lynchon Tools"
def draw(self, context):
layout = self.layout
scn = context.scene
mytool = scn.my_tool
split = layout.split()
# First column
col = split.column()
col.label(text="Import Venue")
col.operator( "xml.lowpolygeneratorparticles")
# Second column, aligned
col = split.column(align=True)
col.label(text="Collapse Venue")
col.operator( "xml.conform_lp_venue")
# Create two columns, by using a split layout.
split = layout.split()
# First column
col = split.column()
col.operator("xml.conformheight")
# Second column, aligned
col = split.column(align=True)
col.prop(mytool, "conform_threshold")
# root for export
col = layout.column(align=True)
col.prop(mytool, "path", text="")
@addon_updater_ops.make_annotations
class UI_PT_LynchoToolsPreferences(bpy.types.AddonPreferences):
bl_name = __package__
# addon updater preferences
auto_check_update = bpy.props.BoolProperty(
name="Auto-check for Update",
description="If enabled, auto-check for updates using an interval",
default=False,
)
updater_intrval_months = bpy.props.IntProperty(
name='Months',
description="Number of months between checking for updates",
default=0,
min=0
)
updater_intrval_days = bpy.props.IntProperty(
name='Days',
description="Number of days between checking for updates",
default=7,
min=0,
max=31
)
updater_intrval_hours = bpy.props.IntProperty(
name='Hours',
description="Number of hours between checking for updates",
default=0,
min=0,
max=23
)
updater_intrval_minutes = bpy.props.IntProperty(
name='Minutes',
description="Number of minutes between checking for updates",
default=0,
min=0,
max=59
)
def draw(self, context):
layout = self.layout
# col = layout.column() # works best if a column, or even just self.layout
mainrow = layout.row()
col = mainrow.column()
# updater draw function
# could also pass in col as third arg
addon_updater_ops.update_settings_ui(self, context)
# Alternate draw function, which is more condensed and can be
# placed within an existing draw function. Only contains:
# 1) check for update/update now buttons
# 2) toggle for auto-check (interval will be equal to what is set above)
# addon_updater_ops.update_settings_ui_condensed(self, context, col)
# Adding another column to help show the above condensed ui as one column
# col = mainrow.column()
# col.scale_y = 2
# col.operator("wm.url_open","Open webpage ").url=addon_updater_ops.updater.website
def register():
bpy.utils.register_class(UI_PT_LynchonMMCPanel)
bpy.utils.register_class(UI_PT_LynchoToolsPreferences)
bpy.utils.register_class(UI_PT_LynchonPanel)
bpy.utils.register_class(MySettings)
bpy.types.Scene.my_tool = PointerProperty(type=MySettings)
def unregister():
bpy.utils.unregister_class(UI_PT_LynchonMMCPanel)
bpy.utils.unregister_class(UI_PT_LynchonPanel)
bpy.utils.unregister_class(UI_PT_LynchoToolsPreferences)
bpy.utils.unregister_class(MySettings)
del bpy.types.Scene.my_tool
Glad that helped. At a glance, not sure why your preferences aren't drawing. Based on the code though looks like you're working in 2.8, and I do notice your panel UI_PT_LynchonPanel does not have a bl_idname, which is required; you can just add bl_idname = 'UI_PT_LynchonPanel'
as a class-level field (might be : actually instead of =).
Beyond that, the console is your friend see if any errors are printed out that occur higher up that prevent the rest of the script from running. Fallback, place print statements in different functions to see that things are being triggered; e.g. print('Pref draw')
atop the preferences draw function, and print('Pref registered')
just after the register statement in register(). Of course, remove these print statements once you resolve the issue.
Thanks again, I solved the drawing issue by placing all the preferences together into the same class and drawing function.
I'm no a coder so I might be missing or doing something stupid. Right now My addon is basically a collection on different scripts I collect and so I can load them all together every time I need. Sometime ago I found an init example which could register all scipts inside an addon folder by just adding the name of the script into a list, this init file is as follows:
As I try to include the updater (so my coworkers can get any update I do) into the addon problems arrive. My problem comes when I try to register the "addon_updater_ops" bl_info, seems that adding it into my register function in my init doesn't work, it keeps telling me it misses a positional argument even if I already have my bl_info inside the init ( I've also tried importing it from the addon_updater_ops as the tutorial explained).
How should I approach this issue, please ask me if you need any additional info or files.
Thanks in advance