Tkinter 标签高度适合内容
我有一个标签,我将在其中放入不同大小的内容。我想知道我需要将标签制作多高,以便我可以调整窗口大小,以便它可以针对不同的内容大小保持不变。我有一个策略,但它似乎比应有的更复杂。
我想将标签设置为给定的宽度和环绕长度:
l = Label(root)
l['width'] = 30
l['wraplength'] = 244
l['text'] = "testing this"
现在我想查询标签以查找使用了多少行。 l['height'] 保持在 0,所以我能想到的最好方法是使用 l.winfo_height() 并将以像素为单位的高度转换为所使用的行数。 dir(l) 中的任何内容似乎都没有直接向我提供信息,但这种策略对于字体更改和其他更改来说很脆弱。
有什么建议吗?
更新:使用 Brian Oakley 的建议(类似于我在 usenet 上得到的建议),我有以下近似的解决方案(需要完善,例如不考虑标签在空白处中断):
import Tkinter as Tk
import tkFont
import random
import sys
def genstr (j):
rno = random.randint(4,50)
ret_val = str(j) + ":"
for i in range (0, rno):
ret_val += "hello" + str(i)
return ret_val
def gendata (lh):
ret_val = []
for i in range(0,lh):
ret_val.append (genstr (i))
return ret_val
data = gendata (100)
root = Tk.Tk()
font = tkFont.Font(family='times', size=13)
class lines:
def __init__ (self):
self.lastct = 1 # remember where the cutoff was last work from there
def count (self, text, cutoff = 400):
global font
no_lines = 1
start_idx = 0
idx = self.lastct
while True:
if idx > len (text):
idx = len (text)
# shrink from guessed value
while font.measure (text[start_idx:idx - 1]) > cutoff:
if idx <= start_idx:
print "error"
sys.exit ()
else:
idx -= 1
self.lastct = idx - start_idx # adjust since was too big
# increase from guessed value (note: if first shrunk then done)
while (idx < len (text)
and font.measure (text[start_idx:idx]) < cutoff):
idx += 1
self.lastct = idx - start_idx # adjust since was too small
# next line has been determined
print "*" + text[start_idx:idx-1] + "*"
if idx == len(text) and font.measure (text[start_idx:]) < cutoff:
return no_lines
elif idx == len(text):
return no_lines + 1
else:
no_lines += 1
start_idx = idx - 1
idx = start_idx + self.lastct
lin = lines()
for i in range(0,len(data)):
lin.count(data[i], 450)
for i in range(0,min(len(data),10)):
l = Tk.Label(root)
l.pack()
l['text'] = data[i]
print i
no = lin.count (data[i], 450)
print "computed lines", no
l['width'] = 50
l['justify'] = Tk.LEFT
l['anchor'] = 'w'
l['wraplength'] = 450
l['padx']=10
l['pady'] = 5
l['height'] = no
l['font'] = font
if i % 2 == 0:
l['background'] = 'grey80'
else:
l['background'] = 'grey70'
root.mainloop()
I have a label into which I am going to put content of different sizes. I would like to know how high I need to make the label so that I can size the window so it can stay the same for the different content sizes. I have a strategy, but it seems more complicated then it should be.
I want to set a label to a given width and wraplength:
l = Label(root)
l['width'] = 30
l['wraplength'] = 244
l['text'] = "testing this"
Now I want to query the label to find how many lines are used. l['height'] stays at 0, so the best I have been able to come up with is to use l.winfo_height() and convert the height given in pixels to the number of lines used. Nothing in dir(l) seems to give me the information directly, but this strategy is fragile to font changes and other changes.
Any suggestions?
Update: using Brian Oakley's suggestion (which is similar to what I got on usenet) I have the following approximation to a solution (needs polishing, e.g. doesn't take into account that Label breaks at whitespace):
import Tkinter as Tk
import tkFont
import random
import sys
def genstr (j):
rno = random.randint(4,50)
ret_val = str(j) + ":"
for i in range (0, rno):
ret_val += "hello" + str(i)
return ret_val
def gendata (lh):
ret_val = []
for i in range(0,lh):
ret_val.append (genstr (i))
return ret_val
data = gendata (100)
root = Tk.Tk()
font = tkFont.Font(family='times', size=13)
class lines:
def __init__ (self):
self.lastct = 1 # remember where the cutoff was last work from there
def count (self, text, cutoff = 400):
global font
no_lines = 1
start_idx = 0
idx = self.lastct
while True:
if idx > len (text):
idx = len (text)
# shrink from guessed value
while font.measure (text[start_idx:idx - 1]) > cutoff:
if idx <= start_idx:
print "error"
sys.exit ()
else:
idx -= 1
self.lastct = idx - start_idx # adjust since was too big
# increase from guessed value (note: if first shrunk then done)
while (idx < len (text)
and font.measure (text[start_idx:idx]) < cutoff):
idx += 1
self.lastct = idx - start_idx # adjust since was too small
# next line has been determined
print "*" + text[start_idx:idx-1] + "*"
if idx == len(text) and font.measure (text[start_idx:]) < cutoff:
return no_lines
elif idx == len(text):
return no_lines + 1
else:
no_lines += 1
start_idx = idx - 1
idx = start_idx + self.lastct
lin = lines()
for i in range(0,len(data)):
lin.count(data[i], 450)
for i in range(0,min(len(data),10)):
l = Tk.Label(root)
l.pack()
l['text'] = data[i]
print i
no = lin.count (data[i], 450)
print "computed lines", no
l['width'] = 50
l['justify'] = Tk.LEFT
l['anchor'] = 'w'
l['wraplength'] = 450
l['padx']=10
l['pady'] = 5
l['height'] = no
l['font'] = font
if i % 2 == 0:
l['background'] = 'grey80'
else:
l['background'] = 'grey70'
root.mainloop()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您是正确的,
height
属性不会改变。该属性不会告诉您实际的高度,只会告诉您其配置的高度。实际高度取决于其中有多少文本、换行长度、字体以及小部件几何形状的管理方式等因素。tkinter Font 对象有一个
measure
方法,可让您确定给定字体的字符串的高度和宽度。您可以获取小部件的字体,并使用该方法来确定字符串需要多少空间。You are correct that the
height
attribute doesn't change. That attribute doesn't tell you the actual height, only the height it is configured to be. The actual height depends on factors such as how much text is in it, the wrap length, the font, and how the widget geometry is managed.tkinter Font objects have a
measure
method which lets you determine how tall and wide a string is for a given font. You can get the font for the widget and use that method to determine how much space is required for your string.