Blender 3D Add-on Script loading failed - python

Heading
I made add-on script.
However loading fail in blender UI.
Error message is '_RestrictContext' object has no attribute 'scene' .
But this script is very well run in blender of Text Editor.
Why don't load this add-on?
bl_info = {
"name": "Add Cube",
"author": "jsh",
"version": (1, 0),
"blender": (2, 68, 0),
"location": "View3D > Tool Shelf > Text make",
"description": "Adds a new Mesh Object",
"warning": "",
"wiki_url": "",
"tracker_url": "http://togetherall.infomaster.co.kr",
"category": "Object"}
import bpy
from bpy.props import *
#
# Store properties in the active scene
#
def initSceneProperties(scn):
bpy.types.Scene.MyInt = IntProperty(
name = "Integer",
description = "Enter an integer")
scn['MyInt'] = 17
bpy.types.Scene.MyFloat = FloatProperty(
name = "Float",
description = "Enter a float",
default = 33.33,
min = -100,
max = 100)
bpy.types.Scene.MyBool = BoolProperty(
name = "Boolean",
description = "True or False?")
scn['MyBool'] = True
bpy.types.Scene.MyEnum = EnumProperty(
items = [('Eine', 'Un', 'One'),
('Zwei', 'Deux', 'Two'),
('Drei', 'Trois', 'Three')],
name = "Ziffer")
scn['MyEnum'] = 2
bpy.types.Scene.MyString = StringProperty(
name = "String2")
scn['MyString'] = "Lorem ipsum dolor sit amet"
return
initSceneProperties(bpy.context.scene)
#
# Menu in UI region
#
class UIPanel(bpy.types.Panel):
bl_label = "Make Text"
bl_space_type = "VIEW_3D"
#bl_region_type = "UI"
bl_region_type = "TOOL_PROPS"
def draw(self, context):
layout = self.layout
scn = context.scene
layout.prop(scn, 'MyInt', icon='BLENDER', toggle=True)
layout.prop(scn, 'MyFloat')
layout.prop(scn, 'MyBool')
layout.prop(scn, 'MyEnum')
layout.prop(scn, 'MyString')
layout.operator("idname_must.be_all_lowercase_and_contain_one_dot")
#
# The button prints the values of the properites in the console.
#
class OBJECT_OT_PrintPropsButton(bpy.types.Operator):
bl_idname = "idname_must.be_all_lowercase_and_contain_one_dot"
bl_label = "make"
def execute(self, context):
bpy.ops.mesh.primitive_cube_add()
return{'FINISHED'}
def printProp(label, key, scn):
try:
val = scn[key]
except:
val = 'Undefined'
#print("%s %s" % (key, val))
return val
def register():
bpy.utils.register_class(UIPanel)
bpy.utils.register_class(OBJECT_OT_PrintPropsButton)
def unregister():
bpy.utils.unregister_class(UIPanel)
bpy.utils.unregister_class(OBJECT_OT_PrintPropsButton)
if __name__ == "__main__":
register()

Blender uses a so called RestrictContext during the register / unregsiter phase of a plugin. This means, you're not allowed to do certain operations on the context because the content might not be ready yet.
In your case, you're doing initSceneProperties(bpy.context.scene) in the global module scope, which means it will be executed immediately after that module is being loaded. Move that initialization code for example in your operator's execute() method and do it when the operator is first run, or any other place where it makes sense (as late as possible, as early as necessary).
See the docs on RestrictContext for an example on how to do this.

Related

How to show Ag grid pop up menu above Quasar QDialog

I am using Ag grid inside quasar QDialog. When the dialog is displayed and I click the column option menu, the Ag grid pop up menu appears behind QDialog, see the picture below:
is there any way to make the ag grid pop up menu shows in the front of the QDialog?
For reference, I see this commmit in Aggrid code:
https://github.com/xh/hoist-react/commit/25522b12155f551fcf95e32211a6cbb8aae8ea35
This adds z-index: 9999 !important to the css style.
Maybe there are ways to add the style using justpy directly or is there more correct way?
My code to produce the above apps is written in python using JustPy v0.10.5 library.
https://github.com/justpy-org/justpy
import justpy as jp
import pandas as pd
def open_dialog(self, msg):
self.dialog.value = True
wm_df = pd.read_csv('https://elimintz.github.io/women_majors.csv').round(2)
def main():
wp = jp.QuasarPage(title='Negative Keyword Editor')
b1 = jp.QBtn(label='Open dialog', color='primary', a=wp)
b1.on('click', open_dialog)
c3_dialog = jp.QDialog(name='alert_dialog', persistent=False, a=wp, maximized=False, full_width=True, transition_show="slide-up", transition_hide="slide-down")
c4_dialog = jp.QCard(a=c3_dialog)
c5_dialog = jp.QCardSection(a=c4_dialog)
c6_dialog = jp.Div(classes='text-h6', a=c5_dialog, text='アカウントを選択:')
c7_dialog = jp.QCardSection(a=c4_dialog, classes='q-pa-none')
grid_dialog = jp.AgGrid(a=c4_dialog, auto_size=True, style = "height: 60vh; width: 100%")
grid_dialog.load_pandas_frame(wm_df)
grid_dialog.options.columnDefs[0].checkboxSelection = True
grid_dialog.options.columnDefs[0].headerCheckboxSelection = True
grid_dialog.options.columnDefs[0].headerCheckboxSelectionFilteredOnly = True
grid_dialog.options.columnDefs[1].filter = 'agTextColumnFilter'
grid_dialog.options.columnDefs[1].cellStyle = {"textAlign": "left"}
grid_dialog.options.defaultColDef.filter = True
grid_dialog.options.defaultColDef.floatingFilter = True
grid_dialog.options.defaultColDef.enableValue = True
grid_dialog.options.defaultColDef.editable = True
grid_dialog.options.defaultColDef.sortable = False
grid_dialog.options.animateRows = True
grid_dialog.options.enableCharts = True
grid_dialog.options.enableRangeSelection = True
grid_dialog.options.statusBar = {
'statusPanels': [
{'statusPanel': 'agTotalAndFilteredRowCountComponent'},
{'statusPanel': 'agTotalRowCountComponent'},
{'statusPanel': 'agFilteredRowCountComponent' },
{'statusPanel': 'agSelectedRowCountComponent' },
{'statusPanel': 'agAggregationComponent' },
],
}
grid_dialog.options.rowSelection = 'multiple'
grid_dialog.options.sideBar = True
c8_dialog = jp.QCardActions(align='right', a=c4_dialog)
c9_dialog = jp.QBtn(flat=True, label='Cancel', color='primary', v_close_popup=True, a=c8_dialog)
c11_dialog = jp.QBtn(flat=True, label='Download', color='primary', v_close_popup=True, a=c8_dialog)
b1.dialog = c3_dialog
return wp
jp.justpy(main)
I add the required css into the wp.css:
wp.css = """
.ag-menu {z-index: 9999 !important;}
"""
reference:
https://github.com/justpy-org/justpy/blob/master/jpcore/webpage.py#L52
the result looks like below, which shows the ag grid pop up menu above the quasar dialog.

optionMenu is not returning value

I have written up a simple UI that requires user to select something from a drop-down list, then using that selection, the code will executes the rest of the stuff
Right now, I am having 2 issues..
1. The 'value' is not exactly returning, as soon as a Format is selected and the OK button is hit... Am I missing something?
2. How can I make my UI closes upon a OK button has been selected?
import maya.cmds as cmds
def mainCode():
...
...
print "UI popping up"
showUI()
print "A format has been selected"
cmds.optionMenu('filmbackMenu', edit = True, value = xxx ) # <-- I want to grab the value from the menu selection and input into this 'value' flag
...
...
def showUI():
if cmds.window("UI_MainWindow", exists = True):
cmds.deleteUI("UI_MainWindow")
cmds.window("UI_MainWindow", title = "User Interface Test", w = 500, h = 700, mnb = False, mxb = False, sizeable = False)
cmds.columnLayout("UI_MainLayout", w = 300, h =500)
cmds.optionMenu("UI_FormatMenu", w = 250, label = "Select a Format")
list01 = ['itemA-01', 'itemB-02', 'itemC-02', 'itemD-01', 'itemE-01', 'itemF-03']
for x in list01:
cmds.menuItem(label = str(x))
cmds.button("UI_SelectButton", label = "OK", w = 200, command=ObjectSelection)
cmds.showWindow("UI_MainWindow") #shows window
def ObjectSelection(*args):
currentFormat = cmds.optionMenu("UI_FormatMenu", query=True, value=True)
print currentFormat
return currentFormat
Use python dictionnaries or class to pass data in your script.
I really don't understand what the problem is.
When you say : "The 'value' is not exactly returning", what do you mean ? Can you tell us what do you get and what do you expect ?
def mainCode():
...
...
showUI()
cmds.optionMenu('filmbackMenu', edit = True, value = xxx ) # <-- I want to grab the value from the menu selection and input into this 'value' flag
...
Here the value selection from the "input value", I guess it is :
cmds.optionMenu('filmbackMenu', edit = True, value = ObjectSelection())
But as there is not filmbackMenu in your code, I'm not sure.
Your second question has been answered on google groups by Justin. You just have to do :
def ObjectSelection(*args):
currentFormat = cmds.optionMenu("UI_FormatMenu", query=True, value=True)
cmds.deleteUI("UI_MainWindow")#close the UI
print currentFormat
return currentFormat
Or maybe "upon a OK button has been selected?" doesn't mean "OK button pressed" ?
If you want to see how use dictionnaries, you can read this other post where I have answered : Maya Python - Using data from UI
You are in a good path to using partial, I recommend you to read about it : Calling back user input values inside maya UI
--- EDIT ---
I tried to create a fully functionnal example :
import maya.cmds as cmds
uiDic = {}
uiDic['this']= 1
def ui_refresh(*args):
uiDic['this'] = cmds.optionMenu("UI_FormatMenu", query=True, value=True)
return uiDic['this']
def showUI():
if cmds.window("UI_MainWindow", exists = True):
cmds.deleteUI("UI_MainWindow")
cmds.window("UI_MainWindow", title = "User Interface Test", w = 500, h = 700, mnb = False, mxb = False, sizeable = False)
cmds.columnLayout("UI_MainLayout", w = 300, h =500)
cmds.optionMenu("UI_FormatMenu", w = 250, label = "Select a Format")
list01 = ['itemA-01', 'itemB-02', 'itemC-02', 'itemD-01', 'itemE-01', 'itemF-03']
for x in list01:
cmds.menuItem(label = str(x))
cmds.button("UI_SelectButton", label = "OK", w = 200, command=ObjectSelection)
uiDic['om_filmback'] = cmds.optionMenu('filmbackMenu' )
list01 = ['itemA-01', 'itemB-02', 'itemC-02', 'itemD-01', 'itemE-01', 'itemF-03']
for x in list01:
cmds.menuItem(label = str(x))
cmds.showWindow("UI_MainWindow") #shows window
def ObjectSelection(*args):
cmds.optionMenu(uiDic['om_filmback'], edit = True, value=ui_refresh())
showUI()

open command sh and call new window?

I'm Italian sorry for my english
I created a plugin, working, now I should be assigned to the yellow - blue keys and information (dreambox enigma2 decoder) command
The blue should run a .sh file in the shell and return to the main menu
the same is true for yellow
the info button it should open a skin, a new information menu .. the closure return to the main menu
*the skin (screen) already includes the buttons drawn
I can not understand the error
here's the listing
class OpenScript(Screen):
skin = '<screen name="main" position="212,15 etc etc >'
def __init__(self, session, args = 0):
Screen.__init__(self, session)
self.session = session
try:
list = listdir('/etc/pandasat/script')
list = [ x[:-3] for x in list if x.endswith('.sh') ]
except:
list = []
#self['key_blue'] = Label(_(' SpeedTest'))
#self['key_yellow'] = Label(_(' Update'))
#self['key_info'] = Label_' Info'))
self['version'] = Label(_('Versione %s' % Version))
self['list'] = MenuList(list)
self['actions'] = ActionMap(['OkCancelActions', 'ColorActions','WizardActions','NumberActions','EPGSelectActions'],{'ok': self.run,
#'key_save': self.run,
'key_exit': self.close,
'red': self.close,
'green': self.run,
#'info': self.ShowAbout,
#'yellow: self.update,
#'blue': self.speedtest,
'cancel': self.close}, -1)
def run(self):
script = self['list'].getCurrent()
if script is not None:
self.session.open(Console, script.replace('_', ' '), cmdlist=['/script/%s.sh' % script])
return
#def speedtest(self): ????????
#def update(self): ?????
#class AboutScreen(Screen):
# skin = '<screen name="InFo" etc etc etc </screen>'
#
Tank' master

TraitsUI - Joining views

Reading the documentation about applying the MVC pattern with TraitsUI, I read the example MVC_demo.py. Now, I'm wondering how to manage multiple "MVC".
I want to write some "includeallMVCs.py" and to have something like:
import MyViewController1, MyViewController2, MyViewController2
class IncludeallMVCs(HasTraits):
view = Include(MyViewController1, MyViewController2, MyViewController3)
Where MyViewController, MyViewController, MyViewController are classes like the MVC_demo sample.
So, the idea is to separate differents views with their controllers, and then "join" all of them in only one "generic" view.
Searching in the examples I found this one: Dynamic Forms Using Instances
Then I modified it to separate an AdultHandler. In this example I use the salary variable to be controlled by AdultHandler.
File: adult.py
from traitsui.api import Handler
class AdultHandler(Handler):
def object_salary_changed (self, info):
if (info.object.salary >= 20000):
print "Good Salary!"
else:
print "Bad Salary"
File: adult_model.py
from adult import AdultHandler
class AdultSpec ( HasTraits ):
""" Trait list for adults (assigned to 'misc' for a Person when age >= 18).
"""
marital_status = Enum( 'single', 'married', 'divorced', 'widowed' )
registered_voter = Bool
military_service = Bool
salary = Int
traits_view = View(
'marital_status',
'registered_voter',
'military_service',
'salary',
handler = AdultHandler()
)
if __name__ == '__main__':
a = AdultSpec()
a.configure_traits()
File: main.py
from adult_model import AdultSpec
class Person ( HasTraits ):
""" Demo class for demonstrating dynamic interface restructuring.
"""
datainput = Instance( AdultSpec )
# Interface for attributes that depend on the value of 'age':
spec_group = Group(
Group(
Item( name = 'datainput', style = 'custom' ),
show_labels = False
),
label = 'Additional Info',
show_border = True
)
# A simple View is enough as long as the right handler is specified:
view = View(
Group(
spec_group
),
title = 'Using MVC',
buttons = [ 'OK' ],
resizable = True,
width = 300
)
# Create the demo:
demo = Person( datainput = AdultSpec() )
# Run the demo (if invoked from the command line):
if __name__ == '__main__':
demo.configure_traits()

Python : Packing a gtk.TreeView and a gtk.Menu in a top level gtk.Window

I'm trying to add a simple menubar to my lister window :
(see / toggle "FIXME" to get to the core of the problem : I get either a menu, or a treeview (and a warning) but not both.)
#!/usr/bin/env python
import os, stat, time
import pygtk
import gtk
import subprocess
folderxpm = [
"17 16 7 1",
" c #000000",
". c #808000",
"X c yellow",
"o c #808080",
"O c #c0c0c0",
"+ c white",
"# c None",
"#################",
"#################",
"##+XXXX.#########",
"#+OOOOOO.########",
"#+OXOXOXOXOXOXO. ",
"#+XOXOXOXOXOXOX. ",
"#+OXOXOXOXOXOXO. ",
"#+XOXOXOXOXOXOX. ",
"#+OXOXOXOXOXOXO. ",
"#+XOXOXOXOXOXOX. ",
"#+OXOXOXOXOXOXO. ",
"#+XOXOXOXOXOXOX. ",
"#+OOOOOOOOOOOOO. ",
"# ",
"#################",
"#################"
]
folderpb = gtk.gdk.pixbuf_new_from_xpm_data(folderxpm)
filexpm = [
"12 12 3 1",
" c #000000",
". c #ffff04",
"X c #b2c0dc",
"X XXX",
"X ...... XXX",
"X ...... X",
"X . ... X",
"X ........ X",
"X . .... X",
"X ........ X",
"X . .. X",
"X ........ X",
"X . .. X",
"X ........ X",
"X X"
]
filepb = gtk.gdk.pixbuf_new_from_xpm_data(filexpm)
interface = """
<ui>
<menubar name="MenuBar">
<menu action="File">
<menuitem action="New"/>
<menuitem action="Open"/>
<menuitem action="Save"/>
<menuitem action="Quit"/>
</menu>
<menu action="Edit">
<menuitem action="Preferences"/>
</menu>
<menu action="Help">
<menuitem action="About"/>
</menu>
</menubar>
</ui>
"""
class Nitpick:
column_names = ['Name', 'Size', 'Mode', 'Last Changed']
def delete_event(self, widget, event, data=None):
gtk.main_quit()
return False
def __init__(self, dname = None):
cell_data_funcs = (None, self.file_size, self.file_mode,
self.file_last_changed)
mywindow = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window = gtk.Window()
self.window.set_size_request(400, 600)
self.window.connect("delete_event", self.delete_event)
listmodel = self.make_list(dname)
# create the TreeView
self.treeview = gtk.TreeView()
mytreeview = gtk.TreeView()
# create the TreeViewColumns to display the data
self.tvcolumn = [None] * len(self.column_names)
cellpb = gtk.CellRendererPixbuf()
self.tvcolumn[0] = gtk.TreeViewColumn(self.column_names[0], cellpb)
self.tvcolumn[0].set_cell_data_func(cellpb, self.file_pixbuf)
cell = gtk.CellRendererText()
self.tvcolumn[0].pack_start(cell, False)
self.tvcolumn[0].set_cell_data_func(cell, self.file_name)
self.treeview.append_column(self.tvcolumn[0])
for n in range(1, len(self.column_names)):
cell = gtk.CellRendererText()
self.tvcolumn[n] = gtk.TreeViewColumn(self.column_names[n], cell)
if n == 1:
cell.set_property('xalign', 1.0)
self.tvcolumn[n].set_cell_data_func(cell, cell_data_funcs[n])
self.treeview.append_column(self.tvcolumn[n])
self.treeview.connect('row-activated', self.open_file)
self.scrolledwindow = gtk.ScrolledWindow()
self.scrolledwindow.add(self.treeview)
# FIXME (toggle lister and menu)
# self.window.add(self.scrolledwindow)
self.treeview.set_model(listmodel)
# Menu
vbox = gtk.VBox()
uimanager = gtk.UIManager()
accelgroup = uimanager.get_accel_group()
self.window.add_accel_group(accelgroup)
self.actiongroup = gtk.ActionGroup("uimanager")
self.actiongroup.add_actions([
("New", gtk.STOCK_NEW, "_New", None, "Create a New Document"),
("Open", gtk.STOCK_OPEN, "_Open", None, "Open an Existing Document"),
("Save", gtk.STOCK_SAVE, "_Save", None, "Save the Current Document"),
("Quit", gtk.STOCK_QUIT, "_Quit", None, "Quit the Application", lambda w: gtk.main_quit()),
("File", None, "_File"),
("Preferences", gtk.STOCK_PREFERENCES, "_Preferences", None, "Edit the Preferences"),
("Edit", "None", "_Edit"),
("About", gtk.STOCK_ABOUT, "_About", None, "Open the About dialog"),
("Help", "None", "_Help")
])
uimanager.insert_action_group(self.actiongroup, 0)
uimanager.add_ui_from_string(interface)
menubar = uimanager.get_widget("/MenuBar")
vbox.pack_start(menubar, False)
vbox.pack_start(self.scrolledwindow, False)
self.window.add(vbox)
self.window.show_all()
return
# Funcs
def make_list(self, dname=None):
if not dname:
self.dirname = os.path.expanduser('~')
else:
self.dirname = os.path.abspath(dname)
self.window.set_title("Nitpicker : " + self.dirname)
files = [f for f in os.listdir(self.dirname) if f[0] <> '.']
files.sort()
files = ['..'] + files
listmodel = gtk.ListStore(object)
for f in files:
listmodel.append([f])
return listmodel
def open_file(self, treeview, path, column):
model = treeview.get_model()
iter = model.get_iter(path)
filename = os.path.join(self.dirname, model.get_value(iter, 0))
filestat = os.stat(filename)
# print filename
if stat.S_ISDIR(filestat.st_mode):
new_model = self.make_list(filename)
treeview.set_model(new_model)
else:
subprocess.call(["play", filename])
# print filename + "is a file!!"
return
def on_selection_changed(selection, f):
model, paths = selection.get_selected_rows()
if paths:
# do the thing!
print selection + f
self.treeView = gtk.TreeView(mymodel)
selection = self.treeView.get_selection()
selection.connect('changed', on_selection_changed)
def file_pixbuf(self, column, cell, model, iter):
filename = os.path.join(self.dirname, model.get_value(iter, 0))
filestat = os.stat(filename)
if stat.S_ISDIR(filestat.st_mode):
pb = folderpb
else:
pb = filepb
cell.set_property('pixbuf', pb)
return
def file_name(self, column, cell, model, iter):
cell.set_property('text', model.get_value(iter, 0))
return
def file_size(self, column, cell, model, iter):
filename = os.path.join(self.dirname, model.get_value(iter, 0))
filestat = os.stat(filename)
cell.set_property('text', filestat.st_size)
return
def file_mode(self, column, cell, model, iter):
filename = os.path.join(self.dirname, model.get_value(iter, 0))
filestat = os.stat(filename)
cell.set_property('text', oct(stat.S_IMODE(filestat.st_mode)))
return
def file_last_changed(self, column, cell, model, iter):
filename = os.path.join(self.dirname, model.get_value(iter, 0))
filestat = os.stat(filename)
cell.set_property('text', time.ctime(filestat.st_mtime))
return
def main():
gtk.main()
if __name__ == "__main__":
flcdexample = Nitpick()
main()
The error (if I self.window.add(self.scrolledwindow))
$ nitpick.py
/home/px/scripts/nitpick.py:157: GtkWarning: Attempting to add a widget with type GtkVBox to a GtkWindow, but as a GtkBin subclass a GtkWindow can only contain one widget at a time; it already contains a widget of type GtkScrolledWindow
self.window.add(vbox)
I'm very new to OOP so bear with me please ; I need three objets here : A gtk.TreeView, a gtk.Menu and a toplevel gtk.Window, when apparently I have two : A gtk.Menu and gtk.TreeView that is the toplevel gtk.Window, hence the error, am I right ?
How do I separate the three elements and put the first two into the last one?
why is vbox.pack_start(self.scrolledwindow, False) apparently not working?
OK, I found out : I was using the wrong argument for
vbox.pack_start(self.scrolledwindow)

Categories

Resources