maya python textField + object name Assistance Please - python

Here is my plan. First create a joint and open your node editor. When you got your joint created, name it "A_Joint" hit "load joint" after running the script, then hit "test" upon hitting test, you should get a node created with the name "A_Joint_firstGuy"
the objective of this script is to create a node based on the name of whatever you loaded into the textField. It will take the name of the selected object and add it to the front of the name of the node
Atleast thats what should happen, but in truth I lack the knowledge to figure this out and every google search has thus far been fruitless. The script is down below for anyone willing to take a crack at it, thank you for your time and I hope to hear back from you:
https://drive.google.com/file/d/1NvL0MZCDJcKAnVu6voVNYbaW0HurZ6Rh/view?usp=sharing
Or here, in SO format:
import maya.cmds as cmds
if cmds.window(window, exists =True):
cmds.deleteUI(window)
window = cmds.window(title = "DS Selection Loader Demo", widthHeight=(300, 200) )
cmds.columnLayout(adjustableColumn=True)
def sld_loadHelperJoint():
sel = cmds.ls(selection=True)
selString = " ".join(sel)
add = cmds.textField('sld_surfaceTextHJ', edit=True, text=selString)
#def sld_loadParentJoint():
# sel = cmds.ls(selection=True)
# selString = " ".join(sel)
# add = cmds.textField('sld_surfaceTextPJ', edit=True, text=selString)
def createNode():
testNode = cmds.createNode( 'transform', selString = "sld_surfaceTextHJ", name = '_firstGuy' )
cmds.columnLayout(adjustableColumn=True)
sld_textFld = cmds.textField('sld_surfaceTextHJ', width =240)
cmds.button( label='Load Helper Joint', command = "sld_loadHelperJoint()")
cmds.setParent('..')
#cmds.columnLayout(adjustableColumn=True)
#name = cmds.textField('sld_surfaceTextPJ', width =240)
#cmds.button( label="Load Parent Joint", command = "sld_loadParentJoint()")
#cmds.setParent('..')
testNode = cmds.createNode( 'transform', name = textField +'_firstGuy' )
# you must first create "def" group for the attributes you
# want to be created via button, "testNode" is our example
# Connect the translation of two nodes together
#cmds.connectAttr( 'firstGuy.t', 'secondGuy.translate' )
# Connect the rotation of one node to the override colour
# of a second node.
#cmds.connectAttr( 'firstGuy.rotate', 'secondGuy.overrideColor' )
cmds.showWindow (window)

OK, there's a few things going on here to consider.
First, Maya gui widgets look like strings -- just like you make a polyCube and it comes back to you as the string 'pCube1', a widget will come back as a string like 'myWindow' or 'textField72'. Just like working with scene objects, you always need to capture the results of a command so you know what it's really called -- you can't guarantee you'll get the name you asked for, so always capture the results.
So you want to do something like this, just to get the graphics going:
window = cmds.window(title='selection loader demo')
column = cmds.columnLayout(adj=True)
sld_textFld = cmds.textField('sld_surfaceTextHJ', width =240)
load_button = cmds.button( label='Load Helper Joint')
cmds.show_window(window)
If you needed to ask what's in the textField, for example, you'd do:
text_contents = cmds.textField(sld_textFld, q=True, text=True)
You notice that's with the variable, not the string, so we're sure we have whatever worked.
To make the button use that information, though, the button script needs to have access to the variable. There are several ways to do this -- it's a common stack overflow question -- but the easiest one is just to define the button command where you already have that variable. So the above sample becomes:
window = cmds.window(title='selection loader demo')
column = cmds.columnLayout(adj=True)
sld_textFld = cmds.textField('sld_surfaceTextHJ', width =240)
def set_textfield(_):
sel = cmds.ls(selection=True)
add = cmds.textField(sld_textFld, edit=True, text=sel[0])
load_button = cmds.button( label='Load Helper Joint', c = set_textfield)
cmds.showWindow(window)
There are two bits here.
One is the _ in the function definition; Maya buttons always call their functions with one argument. There's nothing magical about the underscore, it's just Python slang for "ignore me" -- but if you don't have an argument in the function def, it will fail.
The more important bit is that the button is given the function definition directly, without quotes. You are saying call this function when clicked. If you use the string version -- a holdover from MEL -- you will run into problems later. The reasons are explained in detail here but the TLDR is don't use the the string form. Ever.
Now that the structural pieces are in place, you should be able to either the node creation to the function I called set_textfield() or make a second button\function combo that does the actual node creation, something like:
window = cmds.window(title='selection loader demo')
column = cmds.columnLayout(adj=True)
sld_textFld = cmds.textField('sld_surfaceTextHJ', width =240)
def set_textfield(_):
sel = cmds.ls(selection=True)
cmds.textField(sld_textFld, edit=True, text=sel[0])
load_button = cmds.button( label='Load Helper Joint', c = set_textfield)
def make_node(_):
text_value = cmds.textField(sld_textFld, q = True, text=True)
if text_value:
print "created:", cmds.createNode('transform', n=text_value +'_firstGuy')
else:
cmds.warning("select an object and add it to the window first!")
node_button = cmds.button( label='Make Node', c = make_node)
cmds.showWindow(window)

Related

.set in function is not being found in other function so it's creating an error tkinter python

I'm trying to create a GUI, in the nav menu you can click a cascade option to open another window where you can click roll to generate a set of numbers. It comes up with error. I think it's because the function is called from another function I just don't know how to get that function to call it/ if there is any other ways to fix this. I've tried global functions and looking it up but haven't found anything other than using classes so far, which I don't know how to do.
line 147, in totalRolls
txtresultsOut.set(totalRollResults)
NameError: name 'txtresultsOut' is not defined
Here is the code that is relevant to it. I've called the function to skip having to input all the other code for the main gui window.
def rollSix():
s = 0
numbers = [0,0,0,0]
for i in range(1,5):
numbers[s] = randrange(1,7)
s += 1
numbers.remove(min(numbers))
Result = sum(numbers)
totalRollResults.append(Result)
def totalRolls():
rollOne()
rollTwo()
rollThree()
rollFour()
rollFive()
rollSix()
txtresultsOut.set(totalRollResults)
def rollw():
rollWindow = tix.Tk()
rollWindow.title("Dice Rolls")
diceLabel = Label(rollWindow, text = "Click Roll for your Stats")
diceLabel.grid(row = 0, column = 0)
rollBtn = Button(rollWindow, text = "Roll Stats", command = totalRolls)
rollBtn.grid(row = 1, column = 0)
txtresultsOut = StringVar()
resultsOut = Entry(rollWindow, state = "readonly", textvariable = txtresultsOut)
resultsOut.grid(row = 2, column = 0)
rollw()
first of all I would NOT recommend using StringVar(). You can use the .get() method of Entry to obtain the value inside the same. Try this way and make a global declaration of the Entry whose values you want to get in other functions.
EDIT------------
#you can use the following code to make your entry active to be edited.
entry.configure(state='normal')
# insert new values after deleting old ones (down below)
entry.delete(0,END)
entry.insert(0, text_should_be_here)
# and finally make its state readonly to not let the user mess with the entry
entry.configure(state='readonly')

Calling function from UI class in maya resulting in nonetype error

I'm building a toolbox UI using python in Maya, and I keep on getting a Nonetype error when I call one of the imported functions. This is the script for the toolbox:
class Toolbox():
import maya.cmds as cmds
def __init__(self):
self.window_name = "mlToolbox"
def create(self):
self.delete()
self.window_name = cmds.window(self.window_name)
self.m_column = cmds.columnLayout(p = self.window_name, adj = True)
cmds.button(p=self.m_column,label = 'MyButton', c=lambda *arg: cmds.polySphere(r = 2))
cmds.button(p=self.m_column, label = 'Make_Control', command = lambda *args: self.ControlBTN())
cmds.button(p=self.m_column, label = 'Find Center of All Selected', command = lambda *args: self.CenterBTN())
cmds.button(p=self.m_column, label = 'Find Center of Each Selected Object', command = lambda *args: self.IndiCenterBTN())
self.colorname = cmds.textField(placeholderText = 'Enter color name...')
cmds.button(p=self.m_column, label = 'ChangeColor', command = lambda *args: self.colorBtn())
self.MinAndMax = cmds.textField()
cmds.button(p=self.m_column, label = 'Random Scatter', command = lambda *args: self.ScatterBTN())
cmds.showWindow(self.window_name)
cmds.button(p=self.m_column, label = 'Select Everything', command = lambda *args: self.selectBTN())
def CenterBTN(self):
import CenterSelected
CenterSelected.Locator()
def ScatterBTN(self):
import Scatter
value = cmds.textField(self.MinAndMax, q=True)
Scatter.RandomScatter(value)
cmds.intField(self.moveMin, self.moveMax, self.rotMin, self.rotMax, self.scaleMin, self.scaleMax, e=True, text='')
def IndiCenterBTN(self):
import ManySelected
ManySelected.LocatorMany()
def colorBtn(self):
import ColorControl
value = cmds.textField(self.colorname, q=True, text = True)
ColorControl.colorControl(value)
cmds.textField(self.colorname, e=True, text='')
def selectBTN(self):
import tools
tools.selectAll()
def delete(self):
if cmds.window(self.window_name, exists=True):
cmds.deleteUI(self.window_name)
def ControlBTN(self):
import CreateControl
CreateControl.createControl()
myTool = Toolbox()
myTool.create()
And this is the function that I'm having trouble with:
def RandomScatter(MinAndMax):
import random
import maya.cmds as cmds
Stuff = cmds.ls(sl=True)
i=0
for i in range(random.randint(1,100)):
Stuff.append(cmds.duplicate(Stuff))
cmds.move( (random.randint(MinAndMax[0], MinAndMax[1])), (random.randint(MinAndMax[0], MinAndMax[1])), (random.randint(MinAndMax[0], MinAndMax[1])), Stuff[i], absolute=True )
cmds.rotate( (random.randint(MinAndMax[2], MinAndMax[3])), (random.randint(MinAndMax[2], MinAndMax[3])), (random.randint(MinAndMax[2], MinAndMax[3])), Stuff[i], absolute=True )
cmds.scale( (random.randint(MinAndMax[4], MinAndMax[5])), (random.randint(MinAndMax[4], MinAndMax[5])), (random.randint(MinAndMax[4], MinAndMax[5])), Stuff[i], absolute=True )
i = i+1
RandomScatter() works fine as long as I call it on it's own using a RandomScatter([a, b, c, d, e, f]) format, but when I try to call it Toolbox(), I get "Scatter.py line 21: 'NoneType' object has no attribute 'getitem'" as an error. It also happens when I try to use the intField() command instead of textField(). The UI window builds just fine; the error only happens after I enter input into the text field and press the button that's supposed to call RandomScatter(). It seems like the input isn't making it to the MinAndMax list, so when it reaches "cmds.move( (random.randint(MinAndMax[0]," it can't find anything to put in the MinAndMax[0] slot, or any of the slots after that, but I can't figure out why. Does anyone have any advice?
I didn't test your code and didn't read it totally, but I can already say that your strange "lambda" usage doesn't make any sens.
lambda *args: self.ControlBTN()
this lambda execute self.ControlBTN during the cmds.button definition and provide to it a function which return None.
that like doing that:
self.ControlBTN()
function = def func(): return None
cmds.button(p=self.m_column, label = 'Make_Control', command=function)
I advise you to reread the documentation about the "python lambda".
replace this by:
cmds.button(p=self.m_column, label = 'Make_Control', command=self.ControlBTN)
...
def ControlBTN(self, *args)
...
That should help
good luck
As written self.MinAndMax is a text field; even if you get the value from it it'll be a string and you won't be able to index into it to get the individual items -- and your indexing will be thrown off if any of the numbers are negative or have decimals. The lazy solution is to use a FloatFieldGrp which lets you have 2-4 numberic inputs. It's a bit annoying to get at all of the values at once (see the way it's done below) but it will avoid many issues with trying to parse the text field.
Also, this line doesn't make sense in context:
cmds.intField(self.moveMin, self.moveMax, self.rotMin, self.rotMax, self.scaleMin, self.scaleMax, e=True, text='')
You're not seeing the error because it's failing in the previous line, but the first argument ought to be the name of an existing intField.
In any case, I'd refactor this a bit to keep the argument parsing out of the scatter function, so you can separate out the working logic from the UI parsing logic. It'll make it much easier to spot where things have gone off the rails:
import random
import maya.cmds as cmds
class TestGUI(object):
def __init__(self):
self.window = cmds.window()
self.layout = cmds.rowLayout(nc=3)
self.min_xyz = cmds.floatFieldGrp( numberOfFields=3, label='min', value1=-10, value2=-10, value3=-10 )
self.max_xyz= cmds.floatFieldGrp( numberOfFields=3, label='min', value1=10, value2=10, value3=10 )
cmds.button(label='scatter', c = self.scatter)
cmds.showWindow(self.window)
def scatter(self, *_):
selected = cmds.ls(sl=True)
if not selected:
cmds.warning("select something")
return
min_xyz = (
cmds.floatFieldGrp(self.min_xyz, q=True, v1=True),
cmds.floatFieldGrp(self.min_xyz, q=True, v2=True),
cmds.floatFieldGrp(self.min_xyz, q=True, v3=True)
)
max_xyz = (
cmds.floatFieldGrp(self.max_xyz, q=True, v1=True),
cmds.floatFieldGrp(self.max_xyz, q=True, v2=True),
cmds.floatFieldGrp(self.max_xyz, q=True, v3=True)
)
print "scatter settings:", min_xyz, max_xyz
rand_scatter(selected, min_xyz, max_xyz)
def rand_scatter(selection, min_xyz, max_xyz):
dupe_count = random.randint(1, 10)
duplicates = [cmds.duplicate(selection) for n in range(dupe_count)]
for dupe in duplicates:
destination = [random.randint(min_xyz[k], max_xyz[k]) for k in range(3)]
cmds.xform(dupe, t=destination, absolute=True)
print (dupe, destination)
t = TestGUI() # shows the window; hit 'scatter' to test
My version changes your logic a bit -- you were duplicating your selection list, which would cause the number of items to grow exponentially (as each duplication would also duplicate the previous dupes). I'm not sure if that's inline with your intention or not.
You can avoid the extra lambdas by including a *_ in the actual button callback; it's a minor maya irritant that buttons always have that useless first argument.
As an aside, I'd try not to do imports inside of function bodies. If the imported module is not available, it's better to know at the time this file is imported rather than only when the user clicks a button -- it's much easier to spot a missing module if you do all your imports in a block at the top.

How do I connect custom Attributes to node inputs?

I'm finally in the end game of the Helper Joint script I'm working on and only 1 last problem stands in my way. Here is how the script is supposed to work. Create a joint, name it "Parent_Joint" then create a "multDoubleLinear" node in the node editor, name it "bob, Hit "Load Parent Joint" after selecting the joint you created and hit add attribute. In an ideal world where I'm smarter on this subject, The custom attribute added to the joint would be plugged into bob's "input1" instead I get an error saying "# Error: The source attribute 'Parent_Joint_HelperJntAttr' cannot be found."
In terms of what I've already tried, I put connectAttr beneath addAttr as common sense would dictate that first the attribute must be created before it's connected: but despite this it's just refusing to connect. I know the fault doesn't fall on the "bob.input1" node, because it only brings up the prefixed attribute name for 'Parent_Joint_HelperJntAttr: so my guess is it's just simply my lack of knowledge in writing this particular procedure.
import maya.cmds as cmds
if cmds.window(window, exists =True):
cmds.deleteUI(window)
window = cmds.window(title='DS Attribute adder')
column = cmds.columnLayout(adj=True)
sld_textFld = cmds.textField('sld_surfaceTextHJ', width =240)
def set_textfield(_):
sel = cmds.ls(selection=True)
cmds.textField(sld_textFld, edit=True, text=sel[0])
load_button = cmds.button( label='Load Parent Joint', c = set_textfield)
def add_Attribute(_):
text_value = cmds.textField(sld_textFld, q = True, text=True)
if text_value:
print "attrAdded:"
cmds.addAttr(ln=text_value +'_HelperJntAttr', defaultValue=5.0, minValue=0, attributeType='float', keyable=True)
cmds.connectAttr( text_value +"_HelperJntAttr", 'bob.input1')
else:
cmds.warning("select an object and add it to the window first!")
node_button = cmds.button( label='add attribute', c = add_Attribute)
cmds.showWindow(window)
I know how to use the connectAttr command on default attributes in maya, but where I fall flat is custom attributes. My hope is I come out of this knowing how to write code that both creates and connects the custom attributes of the joint. Thank you in advance for your help
The way you were using addAttr, it was including the joint's name in the attribute name. Attributes are separated with a ., not an _, so your connectAttr also fails because of that.
You also need to initialize your window variable to some default value or it fails on the line where you check if it exists (but window isn't defined at that point).
Here is the script adding the attribute and connecting it as expected:
import maya.cmds as cmds
window = "" # Need to initialize this variable first or it crashes on next line.
if cmds.window(window, exists =True):
cmds.deleteUI(window)
window = cmds.window(title='DS Attribute adder')
column = cmds.columnLayout(adj=True)
sld_textFld = cmds.textField('sld_surfaceTextHJ', width =240)
def set_textfield(_):
sel = cmds.ls(selection=True)
cmds.textField(sld_textFld, edit=True, text=sel[0])
load_button = cmds.button( label='Load Parent Joint', c = set_textfield)
def add_Attribute(_):
text_value = cmds.textField(sld_textFld, q = True, text=True)
if text_value:
print "attrAdded:"
# Attribute must be created this way.
cmds.addAttr(text_value, ln='HelperJntAttr', defaultValue=5.0, minValue=0, attributeType='float', keyable=True)
# Attribute is separated with a dot.
cmds.connectAttr(text_value + ".HelperJntAttr", 'bob.input1')
else:
cmds.warning("select an object and add it to the window first!")
node_button = cmds.button( label='add attribute', c = add_Attribute)
cmds.showWindow(window)

Multiple text fields refusing to load selected objects

The code I made, despite double, triple, and quadruple checking is refusing to load selected items into the text fields, that is assuming you can get maya to get over it's newfound hatred of the cmds.windows function
The errors I'm getting are threefold, if you try to load the code into a new window you will just get
Error: name 'window' is not defined" assuming you make it past that hurdle you will run into 2 problems: the first is just from pasting the code below. The menu will load just fine, but if you hit either "Load A Node" or "Load B Node" you will get the error "# Error: Object 'window1|columnLayout9|sld_surfaceTextHJ' not found.
I never put "sld_surfaceTextHJ" in the code, so I dont know why maya keeps asking for it. If you humor it however and try to change the name 'sld_surfaceTextA' or 'sld_surfaceTextB' to any other name you will get the third error: # Error: name 'window1|columnLayout9|sld_surfaceTextHJ' is not defined.
The script used to work fine loading selections, but it seems that every script I made following this format is refusing to work.
Here it is if you want to take a crack at it
import maya.cmds as cmds
if cmds.window(window, exists =True):
cmds.deleteUI(window)
window = cmds.window(title='DS selection connector demo')
column = cmds.columnLayout(adj=True)
sld_textFldA = cmds.textField('sld_surfaceText1', width =240)
load_button = cmds.button( label='Load A Node', c = set_textfield)
sld_textFldB = cmds.textField('sld_surfaceText2', width =240)
load_button = cmds.button( label='Load B Node', c = set_textfield)
node_button = cmds.button( label='Connect Node', c = make_node)
def set_textfieldA(_):
sel = cmds.ls(selection=True)
cmds.textField(sld_textFldA, edit=True, text=sel[0])
def set_textfieldB(_):
sel = cmds.ls(selection=True)
cmds.textField(sld_textFldB, edit=True, text=sel[0])
def connect_node(_):
text_value = cmds.textField(sld_textFldA, q = True, text=True)
text_value = cmds.textField(sld_textFldB, q = True, text=True)
if text_value:
print "created:", cmds.connectAttr('transform', n=text_value +'_firstGuy')
print "created:", cmds.connectAttr('transform', n=text_value +'_secondGuy')
else:
cmds.warning("select an object and add it to the window first!")
cmds.showWindow( window )
The expected results are rather simple: you hit "Load A Node" on any node you create to load the first Node, Then you hit "Load B Node" on the second node you created: then upon hitting "Connect Node" the translate attribute of your first node should be connected to your second node like the connection editor.
Never mind guys, for anyone interested: here is the fixed code, I still haven't gotten the connect attributes part figured out yet: but for anyone looking for a simple textField selection loader demo, here you go:
import maya.cmds as cmds
if cmds.window(window, exists =True):
cmds.deleteUI(window)
window = cmds.window(title='DS selection connector demo')
column = cmds.columnLayout(adj=True)
sld_textFldA = cmds.textField('sld_surfaceText1', width =240)
load_button = cmds.button( label='Load A Node', c = set_textfield1)
sld_textFldB = cmds.textField('sld_surfaceText2', width =240)
load_button = cmds.button( label='Load B Node', c = set_textfield2)
def set_textfield1(_):
sel = cmds.ls(selection=True)
cmds.textField(sld_textFldA, edit=True, text=sel[0])
def set_textfield2(_):
sel = cmds.ls(selection=True)
cmds.textField(sld_textFldB, edit=True, text=sel[0])
cmds.showWindow( window )

Change the color of a single word in a tk option menu?

So I'm grabbing links of events off a website and putting them into a drop down menu to be selected. My code for the menu:
import Tkinter as tk
from Tkinter import StringVar
selectMenu = tk.Tk()
# #-> this is what I have
# Followed by what you can use
#var = Vars()
#events = var.GetVars('Event')
events = " "
options = []
links = []
#forms = (driver.find_elements_by_class_name("with-cats")) #This is what I have
forms = ["Yolo ","Dad? Closed","Anotha One","Normies! Closed"] #This is so you can try it for yourself
for x in forms:
#info = x.text
info = x #Again, this is so you can try it for yourself
if events in info.lower():
links.append(x)
for link in range(0,len(links)):
#options.append(links[link].text)
options.append(links[link])
list(set(options))
selection = []
for link in range(0,len(options)):
selection.append(options[link])
select = StringVar(selectMenu)
select.set("--None Selected--")
menu = tk.OptionMenu(selectMenu, select, *(selection))
msg = "Which one would you like to attend?"
label = tk.Label(selectMenu, text=msg, font="Helvedica 14")
label.pack(side='top', pady=10)
menu.pack(side="top", pady=10)
selectMenu.attributes('-topmost', True)
selectMenu.mainloop()
So this works fine and dandy, but I would like to improve the look to make it more obvious which events are open. To clarify, an event found that is open and put into the menu may look like "This is a cool event", but one that is closed would be read as "This is a cool event Closed". My aim is to be able to make the foreground red of either just the word Closed or the string containing Closed, whichever is possible if any (And I'm not sure if it's possible because menus and buttons on osx are usually defaulted to system settings, maybe there is a way around this?).
Current: Desired:
According to the documentation for OptionMenu here and here I don't think there is a way to set the color of text.
You might be able to get something close to what you want by using a listBox instead. See post here for the listBox example.
Found a solution! Using a Menu inside of a MenuButton the same way Tkinter creates MenuOptions, I was able to create a custom MenuOption. If you want to add more options, you can use the menbutton.configure() option to edit the button, and menbutton.menu to edit the menu items.
import Tkinter as tk
from Tkinter import Menu, Menubutton
class Vars():
global vari
vari = {}
def GetVars(self, var):
return vari.get(str(var))
def SendVars(self, var, val):
vari[str(var)] = val
class App():
def buttselect(self, link, menbutton, selectMenu):
var = Vars()
var.SendVars("Selection", link) # Store selected event
menbutton.configure(text=link) # Set menu text to the selected event
def prnt(self, link):
var = Vars()
print var.GetVars("Selection") # Print event
def __init__(self, selectMenu):
events = " "
options = []
links = []
forms = ["Yolo ","Dad? Closed","Anotha One","Normies! Closed"] #This is so you can try it for yourself
menbutton = Menubutton (selectMenu, text="--None Selected--", relief="raised")
menbutton.grid()
menbutton.menu = Menu (menbutton, tearoff=0)
menbutton["menu"] = menbutton.menu
#Get a list of event names
for x in forms:
info = x #Again, this is so you can try it for yourself
#If desired event keyword is in an event name, add it to the correct links
if events in info.lower():
links.append(x)
#Remove duplicates
for link in range(0,len(links)):
options.append(links[link])
list(set(options))
#Final list of event names turned into menu commands
for link in options:
if "Closed" in link:
menbutton.menu.add_command( label= link, command= lambda link=link: self.buttselect(link, menbutton, selectMenu), foreground='red')
else:
menbutton.menu.add_command( label= link, command= lambda link=link: self.buttselect(link, menbutton, selectMenu))
b = tk.Button(selectMenu, text="Selection", command= lambda link=link: self.prnt(link)) #Print selected event
b.pack()
msg = "Which one would you like to attend?"
label = tk.Label(selectMenu, text=msg, font="Helvedica 14")
label.pack(side='top', pady=10)
menbutton.pack(side="top", pady=10)
selectMenu = tk.Tk()
selectMenu.attributes('-topmost', True)
app = App(selectMenu)
selectMenu.mainloop()
This results in exactly the result desired:
I found a way!
Let's say x is an optionmenu with options:
options=['Red','Blue','Green']
defopt=tk.StringVar(options[0]) #StringVariable to hold the selected option.
x=tk.OptionMenu(self.optmenuframe,defopt,*options)
Now, get the menu object from the optionmenu and use entryconfig method. That's it!
x.children['menu'].entryconfig(0,foreground='red')
x.children['menu'].entryconfig(1,foreground='blue')
x.children['menu'].entryconfig(2,foreground='green')
#0 is the index of the option you want to apply the configurations to.

Categories