繁体   English   中英

Python3:如何在tkinter / ttk中动态调整按钮文本的大小?

[英]Python3: How to dynamically resize button text in tkinter/ttk?

我想知道如何安排ttk小部件上的文本(比如标签或按钮)来自动调整大小。

更改文本的大小很简单,只需更改样式中的字体即可。 然而,将它挂钩到窗口大小的变化是一个更棘手的问题。 在网上看到我发现了一些提示,但没有发布完整的答案。

因此,下面是一个完整的工作示例,作为我自己的问题的答案发布。 我希望有人发现它有用。 如果有人有进一步的改进建议,我会很高兴看到他们!

下面的示例显示了两种技术,一种是通过重新调整窗口大小来激活(请参阅resize()方法,绑定到<Configure>事件),另一种是直接更改字体大小(请参阅mutate()方法) )。

调整大小工作所需的其他代码是__init__()方法中的网格配置代码。

在运行示例时,两种方法之间存在一些交互,但我认为在“真实”情况下,一种技术就足够了,因此不会出现问题。

from tkinter import *
from tkinter.ttk import *


class ButtonApp(Frame):
    """Container for the buttons."""

    def __init__(self, master=None):
        """Initialize the frame and its children."""

        super().__init__(master)
        self.createWidgets()

        # configure the frame's resize behaviour
        master.columnconfigure(0, weight=1)
        master.rowconfigure(0, weight=1)
        self.grid(sticky=(N,S,E,W))

        # configure resize behaviour for the frame's children
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        # bind to window resize events
        self.bind('<Configure>', self.resize)


    def createWidgets(self):
        """Make the widgets."""

        # this button mutates
        self.mutantButton = Button(self, text='Press Me',
                                   style='10.TButton')
        self.mutantButton.grid(column=0, row=0, sticky=(N,S,E,W))
        self.mutantButton['command'] = self.mutate

        # an ordinary quit button for comparison
        self.quitButton = Button(self, text='Quit', style='TButton')
        self.quitButton.grid(column=0, row=1, sticky=(N,S,E,W))
        self.quitButton['command'] = self.quit


    def mutate(self):
        """Rotate through the styles by hitting the button."""

        style = int(self.mutantButton['style'].split('.')[0])
        newStyle = style + 5
        if newStyle > 50: newStyle = 10
        print('Choosing font '+str(newStyle))
        self.mutantButton['style'] = fontStyle[newStyle]

        # resize the frame

        # get the current geometries
        currentGeometry = self._root().geometry()
        w, h, x, y = self.parseGeometry(currentGeometry)
        reqWidth = self.mutantButton.winfo_reqwidth()
        reqHeight = self.mutantButton.winfo_reqheight()

        # note assume height of quit button is constant at 20.
        w = max([w, reqWidth])
        h = 20 + reqHeight
        self._root().geometry('%dx%d+%d+%d' % (w, h, x, y))


    def parseGeometry(self, geometry):
        """Geometry parser.
        Returns the geometry as a (w, h, x, y) tuple."""

        # get w
        xsplit = geometry.split('x')
        w = int(xsplit[0])
        rest = xsplit[1]

        # get h, x, y
        plussplit = rest.split('+')
        h = int(plussplit[0])
        x = int(plussplit[1])
        y = int(plussplit[2])

        return w, h, x, y


    def resize(self, event):
        """Method bound to the <Configure> event for resizing."""

        # get geometry info from the root window.
        wm, hm = self._root().winfo_width(), self._root().winfo_height()

        # choose a font height to match
        # note subtract 30 for the button we are NOT scaling.
        # note we assume optimal font height is 1/2 widget height.
        fontHeight = (hm - 20) // 2
        print('Resizing to font '+str(fontHeight))

        # calculate the best font to use (use int rounding)
        bestStyle = fontStyle[10] # use min size as the fallback
        if fontHeight < 10: pass # the min size
        elif fontHeight >= 50: # the max size
            bestStyle = fontStyle[50]
        else: # everything in between
            bestFitFont = (fontHeight // 5) * 5
            bestStyle = fontStyle[bestFitFont]

        # set the style on the button
        self.mutantButton['style'] = bestStyle


root = Tk()
root.title('Alice in Pythonland')

# make a dictionary of sized font styles in the range of interest.
fontStyle = {}
for font in range(10, 51, 5):
    styleName = str(font)+'.TButton'
    fontName = ' '.join(['helvetica', str(font), 'bold'])
    fontStyle[font] = styleName
    Style().configure(styleName, font=fontName)

# run the app
app = ButtonApp(master=root)
app.mainloop()
root.destroy()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM