【问题标题】:Making Toplevel resize itself to fit the title使 Toplevel 调整自身大小以适合标题
【发布时间】:2017-06-14 09:48:17
【问题描述】:

考虑:

#!/usr/bin/python

from Tkinter import *

root=Tk()
root.withdraw()

top=Toplevel()
top.title("Some long title")
label = Label(top, text ="short", font=('Times', 18))
label.pack()

root.mainloop()

生成的Toplevel 窗口大到足以容纳内容。但是,看不到标题。如何让窗口自行调整大小以显示内容和标题?

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    你不能做你想做的事。 Tkinter 无法访问有关标题栏的信息。

    【讨论】:

    • 那么,人们是怎么做的呢?我的意思是,没有自尊的应用程序可以容忍隐藏标题!
    • @AlwaysLearning:我认为你错了。我可以轻松地从标题被剪掉的各种程序中创建窗口。
    【解决方案2】:

    经过一些挖掘和测试,我想我找到了可以使用的东西。我们需要使用 tkFont 的导入,并使用actual() 来获取字体信息。

    尝试以下方法:

    from tkinter import *
    import tkinter.font as tkFont
    
    # imports for python 2
    # from Tkinter import *
    # import tkFont
    
    root=Tk()
    root.withdraw()
    
    top=Toplevel()
    
    label_not_settings = Label(top, text ="Some long title")
    label_not_settings.grid(row = 0, column = 0, sticky = 'w')
    
    label_arial_12 = Label(top, text ="Some long title", font = ('Arial', 12))
    label_arial_12.grid(row = 1, column = 0, sticky = 'w')
    
    label = Label(top, text ="Some long title", font=('Times', 18))
    label.grid(row = 2, column = 0, sticky = 'w')
    
    
    empty_font = tkFont.Font()
    label_not_settings_font = tkFont.Font(font = label_not_settings['font'])
    label_arial_12_font = tkFont.Font(font = label_arial_12['font'])
    toplevel_font = tkFont.Font(top.title("Some long title")) # no error comes from this line thought I don't think its actually working as intended.
    label_font = tkFont.Font(font = label['font'])
    
    print('# Results of priting with .actual() "empty_font = tkFont.Font()"')
    print(empty_font.actual())
    print("")
    print("# Results of priting with .actual() on {}".format("label_not_settings_font"))
    print(label_not_settings_font.actual())
    print("")
    print("# Results of priting with .actual() on {}".format("label_arial_12_font"))
    print(label_arial_12_font.actual())
    print("")
    print("# Results of priting with .actual() on {}".format("toplevel_font"))
    print(toplevel_font.actual())
    print("")
    print("# Results of priting with .actual() on {}".format("label_font"))
    print (label_font.actual())
    
    root.mainloop()
    

    对我来说,这导致:

    # Results of priting with .actual() "empty_font = tkFont.Font()"
    {'family': 'Arial', 'size': 12, 'weight': 'normal', 'slant': 'roman', 'underline': 0, 'overstrike': 0}
    
    # Results of priting with .actual() on label_not_settings_font
    {'family': 'Segoe UI', 'size': 9, 'weight': 'normal', 'slant': 'roman', 'underline': 0, 'overstrike': 0}
    
    # Results of priting with .actual() on label_arial_12_font
    {'family': 'Arial', 'size': 12, 'weight': 'normal', 'slant': 'roman', 'underline': 0, 'overstrike': 0}
    
    # Results of priting with .actual() on toplevel_font
    {'family': 'Arial', 'size': 12, 'weight': 'normal', 'slant': 'roman', 'underline': 0, 'overstrike': 0}
    
    # Results of priting with .actual() on label_font
    {'family': 'Times New Roman', 'size': 18, 'weight': 'normal', 'slant': 'roman', 'underline': 0, 'overstrike': 0}
    

    它似乎确实产生了您需要的字体信息。虽然我不是 100% 确定它在调用 toplevel_font.actual() 时会按预期工作,但它会产生与调用空变量相同的结果(我想象它只是说明了默认字体,但我不确定)。此外,如果我创建一个带有文本但没有字体配置的标签,那么它会产生不同的 font.actual() 结果。

    更新:

    我还研究了使用标题栏的功能创建自己的标题栏的问题。到目前为止我遇到的问题是窗口移动,因此当拖动窗口时,标题栏的左上角位于鼠标点,将窗口拖动到显示器一侧时失去自动调整大小功能和无法手动调整窗口大小。

    我想构建一个功能齐全的标题栏是可能的,我会继续努力,因为我有兴趣看看我是否可以制作一个。但现在这里有一些信息来说明创建自己的标题栏的基础知识。

    这段代码来自这篇文章:Can I change the title bar in Tkinter?

    我做了一些小改动,但基本上是一样的。

    from tkinter import *
    
    root = Tk()
    
    def move_window(event):
        root.geometry('+{0}+{1}'.format(event.x_root, event.y_root))
    
    root.overrideredirect(True) # turns off title bar, geometry
    root.geometry('200x100') # set new geometry
    
    # make a frame for the title bar
    title_bar = Frame(root, bg = 'white', relief = FLAT, bd = 2)
    
    # put a close button on the title bar
    close_button = Button(title_bar, text = 'X', relief = FLAT, command = root.destroy)
    
    # a canvas for the main area of the window
    window = Canvas(root, bg='black')
    
    # pack the widgets
    title_bar.pack(expand = 1, fill = X)
    close_button.pack(side = RIGHT)
    window.pack(expand = 1, fill = BOTH)
    # bind title bar motion to the move window function
    title_bar.bind('<B1-Motion>', move_window)
    
    root.mainloop()
    

    编辑:

    话虽如此,我可能只是在每个主要操作系统上进行测试,并在一个好的root.geometry()root.minsize() 上除冰,这将显示完整的标题文本。这可能不是一个优雅的解决方案,例如使用代码计算文本大小并将该大小应用于窗口打开大小,但它应该可以解决问题。

    【讨论】:

    • 在您的第一个示例中,不能保证标签使用的字体与系统在窗口标题栏中使用的字体相同。此外,此代码毫无意义:tkFont.Font(top.title("Some long title"))top.title(...) 只返回一个空字符串,这导致tkFont.Font() 只返回默认字体。
    • @Bryan Oakley:我想知道top.title(...),因为它没有抛出任何错误。这就是我写Though I am not 100% sure it is working as intended when calling toplevel_font.actual() 的原因。我还用一些不同的结果更新了我的答案。
    猜你喜欢
    • 1970-01-01
    • 2012-02-06
    • 2013-10-12
    • 2020-08-26
    • 2016-04-26
    • 1970-01-01
    • 2013-07-26
    • 1970-01-01
    • 2013-06-25
    相关资源
    最近更新 更多