Изменение значка по умолчанию в tkinter OptionMenu?

Я пытаюсь удалить значок «как коробка» по умолчанию из tkinter OptionMenu и заменить его своим собственным файлом изображения. ниже приведен код, который у меня есть на сегодняшний день. Это работает, но мне пришлось добавить последнюю строку, чтобы она отображала изображение стрелки и чтобы OptionMenu функционировал. Тем не менее, изображение стрелки всегда находится сразу после текста, а не в крайнем правом углу OptionMenu, и липкий шов не применяется, поэтому ширина = 140. Я работаю в Python 2.6.

Любые предложения по перемещению изображения вправо?

Default«Что

...
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
...

person Community    schedule 04.11.2012    source источник


Ответы (4)


Вы можете использовать ttk.Combobox вместо виджета:

om = Combobox(root, values=*myOptList)
om.set(myVar)
om.grid(sticky=W + E, padx=5, pady=5)
om.config(compound='right', width=140)
person Peter Wood    schedule 22.03.2016

Вы можете отключить индикатор и не использовать атрибут compound. Создайте стрелку в виде метки с изображением без границ или текста. Затем вы можете использовать place, чтобы поместить метку справа от кнопки (используя атрибут relx). Это то, в чем place действительно хорош.

person Bryan Oakley    schedule 15.10.2015

Вы можете отключить индикатор, а затем использовать собственное изображение индикатора. Далее отрегулируйте положение по своему усмотрению. Проверьте образец фрагмента ниже:

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()
person HardCoder    schedule 24.07.2017

Это не сработает, и, к сожалению, я не вижу простого решения. Основная проблема здесь в том, что OptionMenu — составной виджет. Это потомок Menubutton (который по иронии судьбы помечен как устаревший/устаревший в исходниках tkinter) и содержит виджет-меню.

Afaik параметр изображения, который вы используете, упакован вместе с текстом метки и не будет «отсоединяться» при ваших попытках настройки макета. Более разумным подходом должно быть влияние на индикатор-виджет/представление, которое вы отключили с помощью IndicatorOn=0. Но и здесь не повезло, потому что я просто не могу понять, что это за индикатор...

Кстати, это выглядит как ужасный хак:

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-/

если вы посмотрите на источник tkinter и сравните его с оригинал. Это также причина, по которой вам нужно добавить вторую строку после «инициализации».

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

В подлинном источнике вы можете обнаружить, что первоначальная догадка о том, что кнопка является своего рода радиокнопкой, не так уж далека от поля, но она не помогает (по крайней мере, не мне) решить проблему tkinter. :-(

Мне жаль, что я не мог быть лучше .... позор мне! :( Но в следующий раз постараюсь! ;-)

person Don Question    schedule 07.11.2012