【问题标题】:Static Text on Scrollable Canvas可滚动画布上的静态文本
【发布时间】:2016-03-06 00:17:22
【问题描述】:

我想在可滚动的 tkinter 画布上保持一些文本是静态的或锚定的。它不应随滚动条一起移动。

我该怎么做?

from tkinter import *
root=Tk()
frame=Frame(root,width=300,height=300)
frame.grid(row=0,column=0)
canvas=Canvas(frame,bg='#FFFFFF',width=300,height=300,scrollregion=(0,0,500,500))
hbar=Scrollbar(frame,orient=HORIZONTAL)
hbar.pack(side=BOTTOM,fill=X)
hbar.config(command=canvas.xview)
vbar=Scrollbar(frame,orient=VERTICAL)
vbar.pack(side=RIGHT,fill=Y)
vbar.config(command=canvas.yview)
canvas.config(width=300,height=300)
canvas.config(xscrollcommand=hbar.set, yscrollcommand=vbar.set)
canvas.pack(side=LEFT,expand=True,fill=BOTH)

canvas.create_text(10, 10, text='Static Text # 1', anchor = NW, fill = 'red')
canvas.create_text(10, 100, text='Static Text # 2', anchor = NW, fill = 'red')
canvas.create_text(150, 10, text='Scrollable Text # 1', anchor = NW)
canvas.create_text(150, 100, text='Scrollable Text # 2', anchor = NW)

root.mainloop()

【问题讨论】:

    标签: python scroll tkinter tkinter-canvas


    【解决方案1】:

    如果您不需要文本框是透明的,最简单的做法是不要将文本放在画布上,而是在画布上放置一个标签画布。

    import tkinter as tk
    root = tk.Tk()
    
    c = tk.Canvas(root)
    c.place(x=0, y=0)
    r = c.create_rectangle(100, 100, 200, 200, outline='red',
                           fill='yellow', width=10)
    ct = c.create_text(110, 150, text='canvas text', anchor='w')
    lt = tk.Label(c, text='label text')
    lt.place(x=110, y=110)
    

    如果您确实想要透明度,那么您必须拦截画布和滚动条之间的移动命令,以便将“静态”项目也移动到与原始屏幕(窗口)坐标对应的画布坐标。这很复杂,因为 Scrollbar.set 需要两个分数,所以画布调用 x/yscrollcommand 时有两个分数。同样,移动滚动条滑块会导致滚动条使用分数调用其命令(画布 x/yview),我怀疑这是左上或左下的分数。另一方面,单击滚动条按钮调用带有数字和单位的 x/yview。

    我想我要做的是创建一个包含静态项目 ID 的元组列表,以及项目的 4 个 canvas.bbox 坐标。接下来将canvas.xscrollcommandcanvas.yscrollcommandhbar.setvbar.set 替换为命名为xscrollyscrollxsetyset 的包装器。在每个包装器中,调用被包装的函数。然后调用一个新的static_set 函数,该函数使用 canvas.canvasx/y(screenx/y, gridspacing=1) 将屏幕坐标转换为新的画布坐标,并使用 canvas.coords(item id, *canvas coords) 来放置项目。

    我让你来解决细节。如果您不熟悉NMT Tkinter 参考,请学习使用它。这是上述信息的来源。

    代码编辑:不要对两个标签都使用名称 t。按照 mcu 的建议,将 lt 的父级从 root 更改为画布 c

    【讨论】:

    • Label 将很好地满足我的需求。并且它应该比计算绘制文本的偏移量要少得多。只有我会让画布成为标签的父级,而不是根。
    • 对。如果画布被破坏或隐藏(在上面的代码中使用place_forget),则将画布(上面的c)设为父级会使覆盖的标签消失。我将编辑代码。
    猜你喜欢
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    相关资源
    最近更新 更多