Tkinter OptionMenu: set the width for the longest menu item in the list

Tkinter OptionMenusets the width based on the active menu item. I'm looking for a way to set its width based on the widest menu item, and not currently selected so that the widget does not change size when the user selects another menu item.

The suggested answer in the Tkinter Option Menu Widget Change Widths question hides the problem, but does not solve it. (Hint: not a duplicate!). The accepted answer is for the widget to be sticky both for Wand E. This hides the problem if the suggested column size is wider than all the elements in the field, but does not actually solve the problem.

I have (and prefer to have) a layout column gridwith various widgets that dynamically depends on the width of the widgets. However, I would prefer that the width reported by the widget OptionMenuis the widest element, and not currently selected, as the width of the entire column changes if the user selects an element that is wider than any of the other objects.

All the proposed methods that I have found so far were either sticky so that the widget Wand Ewhich in itself does not solve the problem, but sets an arbitrary constant width that is not associated with the length element, which I do not want to do.

+3
source share
3 answers

, , , . , width " ", "0" . :

  • , .
  • measure, . ( .)
  • 0. " ".

. , Pythonic OptionMenu .., .

def setMaxWidth(stringList, element):
    f = tkFont.nametofont(element.cget("font"))
    zerowidth=f.measure("0")
    w=max([f.measure(i) for i in stringList])/zerowidth

    element.config(width=w)

, . , , .

    for i in stringList:
        print len(i), float(f.measure(i))/float(zerowidth)

:

4 3.83333333333
24 20.1666666667
22 18.5
11 11.1666666667
12 11.3333333333
14 12.6666666667

= . = . , len(max(opts, key=len)) . (, , .) W, ., , "" .

+4

, , OptionMenu, .

from Tkinter import *

root = Tk()

opts = ['bacon', 'cereal', 'eggs']

oMenuWidth = len(max(opts, key=len))

v = StringVar(root)
v.set(opts[0])
oMenu = OptionMenu(root, v, *opts)
oMenu.config(width=oMenuWidth)
oMenu.grid()

mainloop()

, , , .

+2

These are your two options: set a fixed width or rely on the width of the cell to control the width of the widget. Setting an arbitrary fixed width should be trivial, since you are one of the parameters of the content of the widget. Just keep track of the widest element that you place in the widget, and use this width as the necessary width for the widget.

+1
source

All Articles