【问题标题】:Change the width of an updated listbox in a ttk Combobox在 ttk 组合框中更改更新列表框的宽度
【发布时间】:2020-04-20 16:40:43
【问题描述】:

这是对here问答的扩展。

我想创建两个 Combobox,第二个 Combobox 中的项目取决于第一个 Combobox 中的选择。此外,我希望下拉列表框调整大小以适合列表中的文本,如答案here 中所示。但是,我在第二部分遇到了一些困难。我想用 Python 解决这个问题。

我使用 .pack() 和 .forget() 而不是 .place() 和 .place_forget() 得到了不同的结果,但是我无法创建一个可靠的解决方案。如果可能,使用 .place 优于 .pack 或 .grid。

作为一名 MWE,我已从上一个问题中的一个答案中扩展了代码。 c2 的下拉列表框可以很好地调整大小,而 c1 的下拉列表框没有。

import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkfont

def on_combo_configure(event):
    combo = event.widget
    style = ttk.Style()
    # check if the combobox already has the "postoffest" property
    current_combo_style = combo.cget('style') or "TCombobox"
    if len(style.lookup(current_combo_style, 'postoffset'))>0:
        return
    combo_values = combo.cget('values')
    if len(combo_values) == 0:
        return
    longest_value = max(combo_values, key=len)
    font = tkfont.nametofont(str(combo.cget('font')))
    width = font.measure(longest_value + "0") - event.width
    if (width<0):
        # no need to make the popdown smaller
        return
    # create an unique style name using widget's id
    unique_name='Combobox{}'.format(combo.winfo_id())
    # the new style must inherit from curret widget style (unless it's our custom style!) 
    if unique_name in current_combo_style:
        style_name = current_combo_style 
    else:
        style_name = "{}.{}".format(unique_name, current_combo_style)

    style.configure(style_name, postoffset=(0,0,width,0))
    combo.configure(style=style_name)

def update_c1_list(event):
    c1.place_forget()
    _ = c.get()
    if _ == "fruit":
        c1['values'] = ('apples are the best', 'bananas are way more better')
    elif _ == "text":
        c1['values'] = ("here's some text", "and here's some much longer text to stretch the list")
    else:
        pass
    c1.place(x=10,y=40)

root = tk.Tk()
root.title("testing the combobox")
root.geometry('300x300+50+50')

c = ttk.Combobox(root, values=['fruit','text'], state="readonly", width=10)
c.bind('<Configure>', on_combo_configure)
c.bind('<<ComboboxSelected>>', update_c1_list)
c.place(x=10,y=10)

c1 = ttk.Combobox(root, state="readonly", width=10)
c1.bind('<Configure>', on_combo_configure)
c1.place(x=10,y=40)

c2 = ttk.Combobox(root, state="readonly", width=10)
c2.bind('<Configure>', on_combo_configure)
c2.place(x=10,y=70)
c2['values']=('this list resizes fine','because it is updated outside of the function')

root.mainloop()

欢迎任何帮助,谢谢。

【问题讨论】:

    标签: python-3.x tkinter combobox ttk


    【解决方案1】:

    在玩了之后,我想出了一个“即时”更新组合框列表框宽度的函数。但是,这有点像用锤子固定窗户,会引起一些问题。

    def Change_combo_width_on_the_fly(combo,combo_width):
    style = ttk.Style()
    # check if the combobox already has the "postoffest" property
    current_combo_style = combo.cget('style') or "TCombobox"
    combo_values = combo.cget('values')
    if len(combo_values) == 0:
        return
    longest_value = max(combo_values, key=len)
    font = tkfont.nametofont(str(combo.cget('font')))
    width = font.measure(longest_value + "0") - (combo_width*6+23)
    if (width<0):
        # no need to make the popdown smaller
        return
    # create an unique style name using widget's id
    unique_name='Combobox{}'.format(combo.winfo_id())
    # the new style must inherit from curret widget style (unless it's our custom style!) 
    if unique_name in current_combo_style:
        style_name = current_combo_style 
    else:
        style_name = "{}.{}".format(unique_name, current_combo_style)
    
    style.configure(style_name, postoffset=(0,0,width,0))
    combo.configure(style=style_name)
    

    作为MWE,代码可以如下使用:

    import tkinter as tk
    import tkinter.ttk as ttk
    import tkinter.font as tkfont
    
    root = tk.Tk()
    c1 = ttk.Combobox(root, state="readonly", width=10)
    c1.place(x=10,y=40)
    Change_combo_width_on_the_fly(c1,10)
    root.mainloop()
    

    虽然该函数完成了这项工作,但它会在我的代码的其他地方引起问题。特别是,它与以前打包的小部件(滚动条)相混淆。我认为它正在改变最后放置的小部件的样式,但我不知道如何解决这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-01
      • 2021-05-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多