optionMenu is not returning value - python

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()

Related

Maya Custom Push/Relax Script

I'm trying to make a custom script that replicates/imitates the Maya Sculpt Geometry Tool. Basically I have 2 radio buttons, Push and Relax[which imitates the push and relax from the sculpt parameters obviously], a value slider[replicates the max displacement slider]. The radio and reset button works perfectly however I'm having problems with coding the slider. Any help for this one? Thanks in advance.
Please see images for further clarification.
Click here for image
Here is my code:
import maya.cmds as cmds
import maya.mel as mel
if cmds.window("cusWin", exists = True):
cmds.deleteUI("cusWin")
customwindow = cmds.window("cusWin",t= "Push/Relax", wh = (200, 117), s= False, mnb= False, mxb= False)
cmds.frameLayout( label='Push/Relax Modifier', borderStyle='in', cll= False)
cmds.columnLayout(adj = True, columnOffset= ("both", 3))
cmds.radioCollection()
cmds.radioButton(l = "Push", onc= "mel.eval('artUpdatePuttyOperation artPuttyCtx push ;')")
cmds.radioButton(l = "Relax", onc= "mel.eval('artUpdatePuttyOperation artPuttyCtx relax ;')")
cmds.separator(style= "none", h= 3)
DynFsgCol1 = 30
DynFsgCol2 = 50
DynFsgCol3 = 100
valSlider = cmds.floatSliderGrp(l = "Value", field = True, min = 0, max= 5, precision = 4, cw3= (DynFsgCol1, DynFsgCol2, DynFsgCol3 ))
cmds.separator(style= "none", h= 3)
cmds.rowColumnLayout(numberOfColumns=2, columnWidth=[(1,98),(2,100)], columnOffset=[(1,'left',1),(2,'right',95)])
cmds.button(l = "Apply", w= 92, c= 'slider()')
cmds.button(l = "Reset", w= 91, c= 'resetButton()')
cmds.showWindow( customwindow )
def slider():
valueSlider = cmds.floatSliderGrp(valSlider, q= True, value= True)
mel.eval('artPuttyCtx -e -maxdisp valueSlider `currentCtx`;')
def resetButton():
mel.eval('resetTool artPuttyContext;')
There's two different things going on here.
First, by using the string form of the callbacks you lose control over the scope of your functions. It's better to pass the python objects directly. This version does what it looks like your's is intended to do using the callbacks:
import maya.cmds as cmds
import maya.mel as mel
if cmds.window("cusWin", exists = True):
cmds.deleteUI("cusWin")
customwindow = cmds.window("cusWin",t= "Push/Relax", wh = (200, 117), s= False, mnb= False, mxb= False)
cmds.frameLayout( label='Push/Relax Modifier', cll= False)
cmds.columnLayout(adj = True, columnOffset= ("both", 3))
cmds.radioCollection()
push = lambda _: cmds.artPuttyCtx(cmds.currentCtx(), e = True, mtm='push')
relax = lambda _: cmds.artPuttyCtx(cmds.currentCtx(), e = True, mtm='relax')
cmds.radioButton(l = "Push", onc= push)
cmds.radioButton(l = "Relax", onc=relax)
cmds.separator(style= "none", h= 3)
DynFsgCol1 = 30
DynFsgCol2 = 50
DynFsgCol3 = 100
valSlider = cmds.floatSliderGrp(l = "Value", field = True, min = 0, max= 5, precision = 4, cw3= (DynFsgCol1, DynFsgCol2, DynFsgCol3 ))
cmds.separator(style= "none", h= 3)
cmds.rowColumnLayout(numberOfColumns=2, columnWidth=[(1,98),(2,100)], columnOffset=[(1,'left',1),(2,'right',95)])
# put the defs here, where the names of the slider are known
def slider(*_):
valueSlider = cmds.floatSliderGrp(valSlider, q = True, value = True)
cmds.artPuttyCtx(cmds.currentCtx(), e = True, maxdisp = valueSlider)
def resetButton(*_):
cmds.resetTool(cmds.currentCtx())
cmds.button(l = "Apply", w= 92, c= slider)
cmds.button(l = "Reset", w= 91, c= resetButton)
cmds.showWindow( customwindow )
The thing to note is that order in which things are defined allows you to reference the names of controls you've made. (As an aside, you need to handle the nonsense arguments Maya passes on the button and slider callbacks). It's also a good idea to clean up dangling Mel scripts where you can, if you want to make this tool more complex in future it's much harder if you have to work in two languages at once. In this case artUpdatePuttyOperation looks like it's defined when the sculpt tool UI opens, so if you ran this script without the UI I don't think it would work correctly.
The second issue is that you're not explicitly setting an artPuttyCtx with setTool, so this won't work unless the user has already created the right context and activated it.

Switchable Radio Buttons (editing a command)

I'm a bit stuck on how to write the correct syntax for editing a command.
way down in my radioOn and radioOff commands, I would like the enable / disable checkbox to enable or disable the radio buttons.
from functools import partial
import maya.cmds as cmds
def one ():
print '1'
def two ():
print '2'
winID = 'xx'
if cmds.window(winID, exists=True):
cmds.deleteUI(winID)
window = cmds.window(winID, sizeable = False, title="Resolution Switcher", widthHeight=(300, 100) )
cmds.columnLayout( )
cmds.text (label = '')
cmds.text (label = '')
cmds.checkBoxGrp( cat = (1,'left', 20), ncb = 1, l1=' DISABLE', offCommand = partial(radioOn, a), onCommand = partial(radioOff, a) )
a = cmds.radioButtonGrp( cat = [(1,'left', 90),(2, 'left', 100)], numberOfRadioButtons=2, on1 = 'one ()' , on2 = 'two ()' )
cmds.text (label = '')
def radioOff (a, *args):
print 'radios off'
a(ed=True, enable=False)
def radioOn (a, *args):
print 'radios on'
a(ed=True, enable=False)
cmds.showWindow( window )
I've tried to get an idea from examples such as the one shown here, but
but when I put down cmds.radioButtonGrp(a, ed=True, enable=False) it just keeps creating new radio buttons, not unlike what was shown in the example with float fields.
bottom line is - I just want the radio buttons to be greyed out and disabled whenever I hit the checkbox. Speaking of which - Is it possible to grey out the radio buttons the same way float fields can? I noticed that disabling them only makes them unclickable - but not greyed out.
Thank you in advance.
from functools import partial
import maya.cmds as cmds
def one (*args):
print '1'
def two (*args):
print '2'
def radioSwitch (a, state, *args):
if state:
cmds.radioButtonGrp(a, e=True, enable=False)
else:
cmds.radioButtonGrp(a, e=True, enable=True)
winID = 'xx'
if cmds.window(winID, exists=True):
cmds.deleteUI(winID)
window = cmds.window(winID, sizeable = False, title="Resolution Switcher", widthHeight=(300, 100) )
cmds.columnLayout( )
cmds.text (label = '')
cmds.text (label = '')
cb_disable = cmds.checkBoxGrp( cat = (1,'left', 20), ncb = 1, l1=' DISABLE', offCommand = "" , onCommand = "" )
a = cmds.radioButtonGrp( cat = [(1,'left', 90),(2, 'left', 100)], enable=True, numberOfRadioButtons=2, on1 = one , on2 = two )
cmds.checkBoxGrp(cb_disable, e=1, offCommand = partial(radioSwitch, a, False))
cmds.checkBoxGrp(cb_disable, e=1, onCommand = partial(radioSwitch, a, True))
cmds.text (label = '')
cmds.showWindow( window )

Blender 3D Add-on Script loading failed

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.

Python sqlite3, tkinter display multible rows

I am new to python and recently i make dictionary using Python and Sqlite3 with tkinter.
When I run the code it returns multiple line in IDLE but in the GUI its only display the last result. I would like to display all the information in the GUI. Thanks you for any help and suggestion.
import tkinter
import sqlite3
class Dictionary:
def __init__(self,master =None):
self.main_window = tkinter.Tk()
self.main_window.title("Lai Mirang Dictionary")
self.main_window.minsize( 600,400)
self.main_window.configure(background = 'paleturquoise')
self.frame1 = tkinter.Frame()
self.frame2= tkinter.Frame(bg = 'red')
self.frame3 =tkinter.Text( foreground = 'green')
self.frame4 = tkinter.Text()
self.lai_label = tkinter.Label(self.frame1,anchor ='nw',font = 'Times:12', text = 'Lai',width =25,borderwidth ='3',fg='blue')
self.mirang_label = tkinter.Label(self.frame1,anchor ='ne',font = 'Times:12', text = 'Mirang',borderwidth ='3',fg ='blue')
self.lai_label.pack(side='left')
self.mirang_label.pack(side = 'left')
self.kawl_buttom= tkinter.Button(self.frame2 ,fg = 'red',font = 'Times:12',text ='Kawl',command=self.dic,borderwidth ='3',)
self.lai_entry = tkinter.Entry(self.frame2, width= 28, borderwidth ='3',)
self.lai_entry.focus_force()
self.lai_entry.bind('<Return>', self.dic,)
self.lai_entry.configure(background = 'khaki')
self.lai_entry.pack(side='left')
self.kawl_buttom.pack(side = 'left')
self.value = tkinter.StringVar()
self.mirang_label= tkinter.Label(self.frame3,font = 'Times:12',fg = 'blue',textvariable = self.value,justify = 'left',wraplength ='260',width = 30, height = 15,anchor = 'nw')
self.mirang_label.pack()
self.mirang_label.configure(background = 'seashell')
self.copyright_label = tkinter.Label(self.frame4,anchor ='nw',font = 'Times:12:bold',text = "copyright # cchristoe#gmail.com",width = 30,borderwidth = 3, fg = 'purple',)
self.copyright_label.pack()
self.frame1.pack()
self.frame2.pack()
self.frame3.pack()
self.frame4.pack()
tkinter.mainloop()
self.main_window.quit()
def dic(self, event = None):
conn = sqlite3.connect('C:/users/christoe/documents/sqlite/laimirangdictionary.sqlite')
c = conn.cursor()
kawl = self.lai_entry.get()
kawl = kawl + '%'
c.execute("SELECT * FROM laimirang WHERE lai LIKE ?", (kawl,))
c.fetchall
for member in c:
out = (member)
self.value.set(out)
print(out, )
dic=Dictionary()
You need to change:
c.execute("SELECT * FROM laimirang WHERE lai LIKE ?", (kawl,))
c.fetchall
for member in c:
out = (member)
self.value.set(out)
print(out, )
To:
for member in c.execute("SELECT * FROM laimirang WHERE lai LIKE ?", (kawl,)):
current_text = self.value.get()
new_text = current_text +( "\n" if current_text else "") +" ".join(member)
self.value.set(new_text)
The new version gets the current value of the StringVar value and then appends the results returned with a space inbetween for each row returned with each row on its own line. What you were doing however involved just updating the StringVar to be the current member object, and therefore it only ever had the last values.
This is how it looks with more than one line:

PyGTK custom ComboBox behavior

I'm trying to create a custom ComboBox that behaves like the one in here: http://chir.ag/projects/name-that-color/
I've got two problems right now:
I can't seem to find a way to have a scrollbar on the side; the gtk.rc_parse_string function should do that, since the ComboBox widget has a "appears-as-list" style property, but my custom widget seems unaffected for some reason.
When you select a color from my widget, then click the ComboBox again, instead of showing the selected item and its neighbours, the scrolled window starts from the top, for no apparent reason.
This is the code, you can pretty much ignore the __load_name_palette method. You need the /usr/share/X11/rgb.txt file to run this code, it looks like this: http://pastebin.com/raw.php?i=dkemmEdr
import gtk
import gobject
from os.path import exists
def window_delete_event(*args):
return False
def window_destroy(*args):
gtk.main_quit()
class ColorName(gtk.ComboBox):
colors = []
def __init__(self, name_palette_path, wrap_width=1):
gtk.ComboBox.__init__(self)
liststore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING,
gobject.TYPE_STRING)
name_palette = self.__load_name_palette(name_palette_path)
for c in name_palette:
r, g, b, name = c
if ((r + g + b) / 3.) < 128.:
fg = '#DDDDDD'
else:
fg = '#222222'
bg = "#%02X%02X%02X" % (r, g, b)
liststore.append((name, bg, fg))
self.set_model(liststore)
label = gtk.CellRendererText()
self.pack_start(label, True)
self.set_attributes(label, background=1, foreground=2, text=0)
self.set_wrap_width(wrap_width)
if len(name_palette) > 0:
self.set_active(0)
self.show_all()
def __load_name_palette(self, name_palette_path):
if exists(name_palette_path):
try:
f = open(name_palette_path,'r')
self.colors = []
palette = set()
for l in f:
foo = l.rstrip().split(None,3)
try:
rgb = [int(x) for x in foo[:3]]
name, = foo[3:]
except:
continue
k = ':'.join(foo[:3])
if k not in palette:
palette.add(k)
self.colors.append(rgb + [name])
f.close()
return self.colors
except IOError as (errno, strerror):
print "error: failed to open {0}: {1}".format(name_palette_path, strerror)
return []
else:
return []
if __name__ == '__main__':
win = gtk.Window()
#colname = ColorName('./ntc.txt')
colname = ColorName('/usr/share/X11/rgb.txt')
gtk.rc_parse_string("""style "mystyle" { GtkComboBox::appears-as-list = 1 }
class "GtkComboBox" style "mystyle" """)
print 'appears-as-list:', colname.style_get_property('appears-as-list')
model = gtk.ListStore(gobject.TYPE_STRING)
hbox = gtk.HBox()
win.add(hbox)
hbox.pack_start(colname)
win.connect('delete-event', window_delete_event)
win.connect('destroy', window_destroy)
win.show_all()
gtk.main()
The problem was the self.show_all() line. Also, you can't have a list AND a wrap_width != 1

Categories

Resources