Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python Tkinter-如何计算扩展标签中显示的字符数?_Python_Tkinter - Fatal编程技术网

python Tkinter-如何计算扩展标签中显示的字符数?

python Tkinter-如何计算扩展标签中显示的字符数?,python,tkinter,Python,Tkinter,我的窗口上有一些小部件。标签lb3随我的窗口一起展开。我想把长数组中的一些字符放在那里。因此,如果窗口很大,则必须有更多的字符,如果窗口的大小较小,则字符数较少。 因此,我需要知道标签的当前高度和宽度(以字符为单位)。 我的问题有一个例子: import Tkinter as tk import tkFont import sys import os last_event_H = 0 last_event_W = 0 LONG_ARRAY = '' # when window siz

我的窗口上有一些小部件。标签lb3随我的窗口一起展开。我想把长数组中的一些字符放在那里。因此,如果窗口很大,则必须有更多的字符,如果窗口的大小较小,则字符数较少。 因此,我需要知道标签的当前高度和宽度(以字符为单位)。 我的问题有一个例子:

import Tkinter as tk
import tkFont
import sys
import os    

last_event_H = 0
last_event_W = 0
LONG_ARRAY = ''

# when window sized
def sizing(event):
    global last_event_H
    global last_event_W
    global LONG_ARRAY
    if (event.width == last_event_W and event.height == last_event_H):
        return
    last_event_H = event.height
    last_event_W = event.width

    width_in_chars = lb3['width']
    height_in_chars = lb3['height']
    first_shown = int(lb1_text.get())
    lb3_text.set(LONG_ARRAY[first_shown:first_shown + width_in_chars * height_in_chars])
    lb2_text.set(LONG_ARRAY[first_shown + width_in_chars * height_in_chars] + ' ...')

class WrappingLabel(tk.Label):
    '''a type of Label that automatically adjusts the wrap to the size'''
    def __init__(self, master=None, **kwargs):
        tk.Label.__init__(self, master, **kwargs)
        self.bind('<Configure>', lambda e: self.config(wraplength=self.winfo_width()))

if __name__ == '__main__':
    root = tk.Tk()
    root.geometry("1280x640")
    dFont=tkFont.Font(family="Arial", size=30) # fixed Font
    LONG_ARRAY = 'a' * 100000 # of symbols

    tb_date = tk.Entry(root, font=dFont)
    tb_date.grid(column=0, row=0, columnspan=3, sticky=tk.NSEW)
    bt_find = tk.Button(root, text="...", font=dFont)
    bt_find.grid(column=9, row=0, columnspan=2, sticky=tk.NSEW)

    lb1_text = tk.StringVar()
    lb1_text.set("1")
    lb1 = tk.Label(root, textvariable=lb1_text, width=10, font=dFont, anchor=tk.NW)
    lb1.grid(column=0, row=1, sticky=tk.NSEW)

    lb2_text = tk.StringVar()
    lb2 = tk.Label(root, textvariable=lb2_text, width=10, font=dFont, anchor=tk.NW)
    lb2.grid(column=1, row=10, columnspan=9, sticky=tk.NSEW)

    lb3_text = tk.StringVar()
    lb3 = WrappingLabel(root, textvariable=lb3_text, font=dFont, anchor=tk.NW, justify=tk.LEFT)
    lb3.grid(column=1, row=1, columnspan=9, rowspan=9, sticky=tk.NSEW)

    for x in range(11):
      tk.Grid.columnconfigure(root, x, weight=1)
    for y in range(11):
      tk.Grid.rowconfigure(root, y, weight=1)
    root.bind("<Configure>", sizing)

    width_in_chars = lb3['width']
    height_in_chars = lb3['height']
    print width_in_chars, height_in_chars # !!!!!!!!!!!!!
    print "-------"
    lb3_text.set(LONG_ARRAY[:width_in_chars * height_in_chars])
    lb2_text.set(LONG_ARRAY[width_in_chars * height_in_chars] + ' ...') # last shown character
    root.mainloop()
将Tkinter作为tk导入
导入tkFont
导入系统
导入操作系统
上次事件\u H=0
上次事件\u W=0
长_数组=“”
#窗口大小时
def大小调整(事件):
全球最后事件
全球最后事件
全局长数组
如果(event.width==last\u event\u W和event.height==last\u event\u H):
返回
最后一个事件\u H=事件高度
最后一个事件\u W=事件宽度
宽度单位字符=lb3['width']
高度(单位字符)=lb3[“高度”]
first_Showed=int(lb1_text.get())
lb3_text.set(长数组[显示的第一个字符:显示的第一个字符+字符中的宽度*字符中的高度])
lb2_text.set(长数组[第一个字符显示+宽度字符*高度字符]+'…)
类包装标签(tk.标签):
''一种标签类型,可自动将包裹调整为大小''
定义初始化(自,主=无,**kwargs):
tk.Label.\uuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
self.bind(“”,lambda e:self.config(wraplength=self.winfo_width())
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
root=tk.tk()
根几何体(“1280x640”)
dFont=tkFont.Font(family=“Arial”,size=30)#固定字体
长数组='a'*100000#个符号
tb_date=tk.Entry(root,font=dFont)
tb_date.grid(列=0,行=0,列span=3,粘性=tk.NSEW)
bt_find=tk.按钮(根,text=“…”,font=dFont)
bt_find.grid(列=9,行=0,列span=2,粘性=tk.NSEW)
lb1_text=tk.StringVar()
lb1_文本集(“1”)
lb1=tk.Label(根,textvariable=lb1_text,宽度=10,字体=dFont,锚点=tk.NW)
lb1.grid(列=0,行=1,粘性=tk.NSEW)
lb2_text=tk.StringVar()
lb2=tk.Label(root,textvariable=lb2_text,width=10,font=dFont,anchor=tk.NW)
lb2.grid(列=1,行=10,列span=9,粘性=tk.NSEW)
lb3_text=tk.StringVar()
lb3=WrappingLabel(根,textvariable=lb3_text,font=dFont,anchor=tk.NW,justify=tk.LEFT)
lb3.grid(column=1,row=1,columnspan=9,rowspan=9,sticky=tk.NSEW)
对于范围(11)内的x:
tk.Grid.columnconfigure(根,x,权重=1)
对于范围(11)内的y:
tk.Grid.rowconfigure(根,y,权重=1)
root.bind(“,大小调整)
宽度单位字符=lb3['width']
高度(单位字符)=lb3[“高度”]
打印宽度(单位:个字符),高度(单位:个字符)!!!!!!!!!!!!!
打印“----”
lb3_text.set(长数组[:字符宽度*字符高度])
lb2_text.set(长数组[字符宽度*字符高度]+'…')最后显示的字符
root.mainloop()
lb3的宽度和高度成员现在设置为0。
因为它可以扩展。还有其他方法吗?

如果你想知道到底可以容纳多少个字符,首先要做的是得到标签的大小。这需要在小部件显示之后进行,因为在显示之前无法知道它的宽度。您可以通过调用
winfo_reqwidth
提前完成此操作,尽管该数字可能大于或小于实际宽度,具体取决于您对
pack
place
grid
使用的选项

一旦知道最大大小,就可以使用字体对象的
font\u measure
方法来计算字符串中的像素数。然后,只需编写一个循环即可计算出适合的最大字符数


在下面的答案中可以找到一个示例,演示如何为过长的标签动态添加“…”:

感谢@BryanOakley提供的有用链接

我对这个问题的解决方案如下 (如果有人能做得更好,请回复)

将Tkinter作为tk导入
导入tkFont
导入系统
导入操作系统
进口对分
长_数组=“”
类键列表(对象):
#对分不接受键函数,所以我们将键构建到序列中。
定义初始化(self,l,key):
self.l=l
self.key=key
定义(自我):
返回len(self.l)
定义uu获取项目uu(自身,索引):
返回self.key(self.l[index],index)
类包装标签(tk.标签):
''一种标签类型,可自动将包裹调整为大小''
定义初始化(自,主=无,**kwargs):
tk.Label.\uuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
自我约束(“”,自我适应)
如果(不是hasattr(self,“原始文本”):
#保留原始文本,以便在小部件增长时恢复它。
self.original_text=self[“text”]
self.font=tkFont.nametofont(self[“font”])
self.font_height=48.88#self.font.metrics('linespace'))
def配合(自身、事件):
最大宽度=事件宽度
max_height=event.height/self.font_height#粗n#行
text=LONG_数组[:2000]#待办事项!!!self.original_文本
实际宽度=self.font.measure(文本)
如果(实际宽度>最大宽度*最大高度):
#原文不合适。继续缩小,直到它缩小为止
i=bisect.bisect_left(键列表(text,key=lambda x,i:self.font.measure(text[:i]+'…')),最大宽度*最大高度)
lb3_text.set(text[:i]+“…”)#TODO!!!self.original_文本
返回self.config(wraplength=self.winfo_width())
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
root=tk.tk()
根几何体(“1280x640”)
dFont=tkFont.Font(family=“Arial”,size=30)#固定字体
长数组='a'*100000#个符号
root.grid\u columnconfigure(0,权重=1)
frame=tk.frame(根)
tk.Grid.rowconfigure(根,0,权重=1)
tk.Grid.columnconfigure(根,0,权重=1)
frame.grid(行=0,列=0,粘性=tk.NSEW)
tb_date=tk.Entry(框架,字体=dFont)
tb_date.grid(列=0,行=0,列span=3,粘性=tk.NSEW)
bt_find=tk.按钮(框架,
import Tkinter as tk
import tkFont
import sys
import os
import bisect

LONG_ARRAY = ''

class KeyList(object):
    # bisect doesn't accept a key function, so we build the key into our sequence.
    def __init__(self, l, key):
        self.l = l
        self.key = key
    def __len__(self):
        return len(self.l)
    def __getitem__(self, index):
        return self.key(self.l[index], index)

class WrappingLabel(tk.Label):
    '''a type of Label that automatically adjusts the wrap to the size'''
    def __init__(self, master=None, **kwargs):
        tk.Label.__init__(self, master, **kwargs)
        self.bind('<Configure>', self.fit)
        if (not hasattr(self, "original_text")):
            # preserve the original text so we can restore it if the widget grows.
            self.original_text = self["text"]
        self.font = tkFont.nametofont(self["font"])
        self.font_height = 48.88 # self.font.metrics('linespace')

    def fit(self, event):
        max_width = event.width
        max_height = event.height / self.font_height # rough n_lines
        text = LONG_ARRAY[:2000] # TODO !!! self.original_text
        actual_width = self.font.measure(text)
        if (actual_width  > max_width * max_height):
            # the original text won't fit. Keep shrinking until it does
            i = bisect.bisect_left(KeyList(text, key=lambda x,i: self.font.measure(text[:i]+ '...')), max_width * max_height)
            lb3_text.set(text[:i] + '...') # TODO !!! self.original_text
        return self.config(wraplength=self.winfo_width())

if __name__ == '__main__':
    root = tk.Tk()
    root.geometry("1280x640")
    dFont=tkFont.Font(family="Arial", size=30) # fixed Font
    LONG_ARRAY = 'a' * 100000 # of symbols

    root.grid_columnconfigure(0, weight=1)
    frame = tk.Frame(root)
    tk.Grid.rowconfigure(root, 0, weight=1)
    tk.Grid.columnconfigure(root, 0, weight=1)
    frame.grid(row=0, column=0, sticky=tk.NSEW)

    tb_date = tk.Entry(frame, font=dFont)
    tb_date.grid(column=0, row=0, columnspan=3, sticky=tk.NSEW)
    bt_find = tk.Button(frame, text="...", font=dFont)
    bt_find.grid(column=9, row=0, columnspan=2, sticky=tk.NSEW)

    lb1_text = tk.StringVar()
    lb1_text.set("1")
    lb1 = tk.Label(frame, textvariable=lb1_text, width=10, font=dFont, anchor=tk.NW)
    lb1.grid(column=0, row=1, sticky=tk.NSEW)

    lb3_text = tk.StringVar() 
    lb3 = WrappingLabel(frame, textvariable=lb3_text, font=dFont, anchor=tk.NW, justify=tk.LEFT)
    #lb3 = tk.Text(frame, font=dFont, state=tk.DISABLED, wrap=tk.CHAR) # bg=frame["bg"], fg='black', 
    lb3.grid(column=1, row=1, rowspan=2, columnspan=9, sticky=tk.NSEW)

    lb2_text = tk.StringVar()
    lb2 = tk.Label(frame, textvariable=lb2_text, width=10, font=dFont, anchor=tk.NW)
    lb2.grid(column=1, row=4, columnspan=9, rowspan=2, sticky=tk.NSEW)
    lb2_text.set('................................................')

    for y in range(11):
        tk.Grid.columnconfigure(frame, y, weight=1)
    for x in range(5):
        tk.Grid.rowconfigure(frame, x, weight=1)
    lb3_text.set(LONG_ARRAY[:2000])
    #lb3.insert(tk.INSERT, LONG_ARRAY[:2000])
    #lb3.insert(tk.END, "")
    root.mainloop()