Changing default icon in tkinter OptionMenu?
Asked Answered
M

4

16

I am trying to remove the default "box like" icon from the tkinter OptionMenu and replace it with my own image file. below is the code I have to date. It is working but I had to add the last line to get it to display the arrow image and for the OptionMenu to function. However, the arrow image is always imedately after the text rather than at the far right of the OptionMenu and sticky does not seam to be aplying hence the width=140. I am working in Python 2.6.

Any sugegestions for moving the image to the right?

Default What I am Getting

...
arrow = PhotoImage(file='arrow.gif')
om = OptionMenu(root,myVar,*myOptList)
om.grid(sticky=W+E,padx=5,pady=5)
om.config(indictoron=0,compound='right',image=arrow,width=140)
om.image=arrow
...
Michaella answered 4/11, 2012 at 15:24 Comment(0)
B
6

You can use the ttk.Combobox widget instead:

om = Combobox(root, values=*myOptList)
om.set(myVar)
om.grid(sticky=W + E, padx=5, pady=5)
om.config(compound='right', width=140)
Bingham answered 22/3, 2016 at 22:46 Comment(7)
Why not a ttk.OptionMenu?Enrico
@Enrico I don't know enough about OptionMenu to recommend it.Bingham
Neither had I until very recently. They're more OptionMenu-like than a Combobox in IMO. Search and ye shall find. They also have a docsting.Enrico
@Enrico I answered this question almost 6 years ago, at a time I was doing a lot of Tkinter development and was having to learn and spend time just to keep up. Learning from someone who is learning is like drinking from a flowing stream, as the saying goes. Unfortunately I'm now pretty stagnant, and have no time.Bingham
I understand—if nothing else my comment will make others aware of its existence.Enrico
@Enrico I appreciate your commitment to getting the best answers for everyone's benefit.Bingham
For anyone interested, here's a link to some good ttk.OptionMenu documentation I found.Enrico
I
5

You can disable the Indicator, and then use your own indicator image. Further adjust the position as it suits. Check the sample snippet below:

from Tkinter import*
import PIL
from PIL import ImageTk, Image

class MyOptionMenu(OptionMenu):
    def __init__(self, master, status, *options):
        self.var = StringVar(master)
        self.img = ImageTk.PhotoImage(Image.open("...")) #replace with your own indicator image
        self.var.set(status)
        OptionMenu.__init__(self, master, self.var, *options)
        self.config(indicatoron=0, image = self.img, font=('calibri',(10)),bg='white',width=12)
        self['menu'].config(font=('calibri',(10)),bg='white')

root = Tk()
mymenu = MyOptionMenu(root, 'Select status', 'a','b','c')
mymenu.pack()
root.mainloop()
Invariant answered 24/7, 2017 at 8:0 Comment(0)
G
4

You can turn off the indicator, and not use the compound attribute. Create the arrow as a label with an image and no borders or text. You can then use place to place the label on the far right of the button (using the relx attribute). This is the type of thing place is really good at.

Gamosepalous answered 15/10, 2015 at 2:22 Comment(0)
B
2

That won't work and regretable i don't see an easy solution. The main problem here is, that OptionMenu is a composite widget. It's a descendant of Menubutton (which ironically is marked as deprecated/obsolte in the tkinter source) and contains a menu-widget.

Afaik the image-option you are using is packed together with the label-text and won't "detach" through your layout-configuration attempts. The more sane approach should be to influence the indicator-widget/representation which you disabled with IndicatorOn=0. But no luck there either, because i just can't figure out what the heck the indicator is...

Btw somehow it looks like an awful hack:

class OptionMenu(Menubutton): 
"""OptionMenu which allows the user to select a value from a menu.""" 
    def __init__(self, master, variable, value, *values, **kwargs):
    ...
    #'command' is the only supported keyword  <--- lol?! WTF?! why?
              callback = kwargs.get('command') 
              if kwargs.has_key('command'): 
                  del kwargs['command'] 
              if kwargs: 
                 raise TclError, 'unknown option -'+kwargs.keys()[0] # yeah sure! - unknown my a** 8-/

if you look at the source of tkinter and compare it to the original. That's also the reason why you have to add a second line after the "initialization"

om.config(indictoron=0,compound='right',image=arrow,width=140)

In the genuine source you may find, that an initial hunch about the button being some kind of a radiobutton, is not so far out of the field, but it doesn't help (at least not me) to solve the tkinter issue. :-(

I'm sorry i couldn't be of any better use.... shame on me! :( But i'll try harder the next time! ;-)

Beauvais answered 7/11, 2012 at 21:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.