TKINTER标签从屏幕上流出.无论如何要检测到这一点



我有一些python代码,使用循环将TKINTER标签放在所讨论的画布上。我的问题是,该数组是否在打印12个标签上循环,有时它们适合屏幕,有时如果标签包含大文字。

如果屏幕宽度已经用尽,是否有一种巧妙的方法来破坏此循环

l_row_start_display=6 
for l in G_DATA_VIEW_LABELS_ARRAY: ## list of lists of labels
      l_cnt=0
      for lab in l:
         l_align='W'             
         lab.grid(row=l_row_start_display,
                column=l_cnt,sticky=l_align) 
         l_cnt+=1
      l_row_start_display+=1

或任何其他想法

谢谢

编辑:

我找到了一种方法,同时仍使用.grid()放置标签。我们可以在MAN窗口中使用框架,然后使用winfo_width()winfo_height()获取框架的大小。使用此信息并在制作每个标签后获得框架的高度和宽度,然后我们可以决定何时结束WALE语句。放置标签时,这将使我们精确。唯一的问题是它将测量当前的帧大小,而不是小部件的大小,因此您可能需要使用数字来将其用于所需的位置。

这是一个示例:

from tkinter import *
root = Tk()
root.geometry("500x300")
l = ["SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT"]
screen = root.winfo_width()
my_frame = Frame(root)
my_frame.pack(expand=True)
last_row = 0
last_column = 0
my_frame_x = my_frame.winfo_width()
my_frame_y = my_frame.winfo_height()
b = True
while b == True:
    for stuff in l:
        if my_frame_x > 450 or my_frame_y > 250:
            print ("Labels cannot be outside of window!")
            b = False
        else:
            lablabel = Label(my_frame) 
            lablabel.config(text = stuff)         
            lablabel.grid(row = last_row, column = last_column)
            last_row += 1
            last_column += 1
            my_frame.update()
            my_frame_x = my_frame.winfo_width()
            my_frame_y = my_frame.winfo_height()
root.mainloop()

您也可以使用.place()布局管理器执行此操作。您需要做的就是定义最大像素X和Y,您希望在。

创建标签

例如,我有一个设置为800x300的窗口,并且一旦达到了像素限制,我就配置了标签生成器以不再创建标签。这是通过定义标签的像素大小来完成的,将该大小添加到下一个位置,然后检查以确保新的X和Y数字不会超过您的预定义尺寸。

请查看此示例:

from tkinter import *
root = Tk()
root.geometry("800x300")
root.minsize(800, 300)

l = ["SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT", "SOME TEXT"]
last_x = 0
last_y = 0
b = True
while b:
    for stuff in l: 
        last_x+=100
        last_y+=30
        if last_x > 700 or last_y > 270:
            b = False
            print ("Labels cannot be outside of window!")
        else:
            lablabel = Label(root) 
            lablabel.config(text = stuff)         
            lablabel.place(x = last_x, y = last_y, width = 100) 
root.mainloop()

我用罗恩·诺里斯(Ron Norris(的答复进行了修补,并提出了这一点。该功能不断将字符添加到字符串中,直到达到其最大宽度为止。它使用分配给小部件的字体来计算像素中的字符串的宽度,然后再将其比较。

def clip_string(widget, string, offset=0, suffix=''):
    max_w = widget.winfo_width() # max width in pixels
    max_w += offset # adjust for offset
    max_w -= (widget['bd']*2) # substract the borderwidth
    font = tkFont.Font(widget, widget.cget("font")) # get widget's font
    new_string = ''
    for char in range(0,len(string)): # add characters until string is at max
        new_string += string[char] # add character
        str_pixels = font.measure(new_string + suffix, widget)
        if str_pixels > (max_w):
            string = new_string + suffix
            break
    return string

这里是快速演示。调整"入口"小部件的宽度,字符串将相应地夹住。

请注意,我们正在导入tkinter.font

from tkinter import *
import tkinter.font as tkFont
def clip_string(widget, string, offset=0, suffix=''):
    max_w = widget.winfo_width() # Gax width in pixels
    max_w += offset # Adjust for offset
    max_w -= (widget['bd']*2) # Substract the borderwidth
    font = tkFont.Font(widget, widget.cget("font")) # Get widget's font
    new_string = ''
    for char in range(0,len(string)): # add chars until string is at max
        new_string += string[char] # add character
        str_pixels = font.measure(new_string + suffix, widget) # Measure
        if str_pixels > max_w:
            string = new_string + suffix
            break
    return string
root = Tk()
root.geometry('375x90')
# Create 'Entry' widget
display_txt = StringVar()
entry_widget = Entry(root,
                    textvariable = display_txt,
                    bd = 7 # borderwidth is taken into account
                    )
entry_widget.place(x=30,y=30, width=300, height=35) # try changing the width
entry_widget.update_idletasks() # needs to update to get real size
string = "this is my really long string so let's see where it gets cut off"
clipped_string = clip_string(
                            widget = entry_widget, # Widget to measure
                            string = string, # Our long string
                            offset = -12, # Offset in pixels
                            suffix = '..' # Chars we want to add
                             )
display_txt.set(clipped_string) # set the new string
root.mainloop()

测量字体是键。

import tkinter.font
from tkinter import *
root = Tk()
# Get a font object
font_obj = tkinter.font.Font()
canvas = Canvas(root)
canvas.grid()
string_list = []
string_list.append('the text that is too wide for the canvas and I need to know that it is')
string_list.append('this text will fit')
# Iterate through the strings, getting the number of pixels it takes.
# Note that this can be configured larger or smaller based on need.
can_width = int(canvas['width'])
i = 0
for s in string_list:
    str_pixels = font_obj.measure(s, canvas)
    # Compare the width of the canvas to the number of str_pixels
    if str_pixels <= can_width:
        y = (i + 1) * 20
        canvas.create_text(10,y,anchor='nw',text=s,font='TkDefault')
        i += 1
    else:
        # Print a warning, ignore, whatever when the string is too long.
        print("'" + s + "'", "is too long to display in canvas")
root.mainloop()

相关内容

最新更新