问题描述
我正在尝试使用Tkinter和Python构建简单的GUI应用程序。 该应用程序应该看起来差不多
------------------------------
Label-1 | Canvas-1
------------------------------
Label-2 | Canvas-2
------------------------------
Label-3 | Canvas-3
------------------------------
. . .
Label-3 | Canvas-3
------------------------------
| scrollbar-horizontal
------------------------------
滚动条应在所有Canvas
对象上同时滚动。
我能够完成那部分,但是当我尝试为每一行设置高度时,我都遇到了问题。
基本上我希望第一行在另一行下并具有预定义的高度。
我决定使用网格管理器来实现这一目标。
下面是一个最小的示例:
import tkinter
import tkinter.font
class LineData(object):
def __init__(self, desc, box):
self.desc = desc
self.box = box
class LinePlotter(object):
def __init__(self, label, canvas, desc, box):
self.label = label
self.canvas = canvas
self.desc = desc
self.box = box
def plot(self):
self.label.set(self.desc)
x1, y1 = self.box[0], 1
x2, y2 = self.box[1], 20
print(self.desc)
print(x1, y1, x2, y2)
print(x2+100, y1, x2+(x2-x1)+100, y2)
self.canvas.create_rectangle(x1, y1, x2, y2, outline="#D1D0CE",
width=4, fill="#D1D0CE")
self.canvas.create_rectangle(x2+100, y1, x2+(x2-x1)+100, y2, outline="#D1D0CE",
width=4, fill="#D1D0CE")
class Plotter(tkinter.Frame):
def __init__(self, parent, lines_data):
super().__init__(parent)
self.parent = parent
self.lines_data = lines_data
def set_scroll_bar(self):
x1, y1, x2, y2 = self.canvases[0].bbox(tkinter.ALL)
x1 = y1 = 0
for c in self.canvases:
t1, u1, t2, u2 = c.bbox(tkinter.ALL)
x1 = min(x1, t1)
x2 = max(x2, t2)
y1 = min(y1, u1)
y2 = max(y2, u2)
print("final=", x1, y1, x2, y2)
for c in self.canvases:
c.config(scrollregion=(x1-5, y1-5, x2+5, y2+5))
def xview(self, *args):
for c in self.canvases:
c.xview(*args)
def initUI(self):
self.scrollX = tkinter.Scrollbar(self, orient=tkinter.HORIZONTAL)
self.scrollX['command'] = self.xview
self.scrollX.grid(row=2, column=1, sticky='NSEW')
self.canvases = []
h = 10
for row_idx, line_data in enumerate(self.lines_data):
desc = tkinter.StringVar()
font = tkinter.font.Font(size=11)
label = tkinter.Label(self, textvariable=desc, font=font,
height=h)
label.grid(row=row_idx, column=0, sticky=tkinter.W)
canvas = tkinter.Canvas(self, bg='white',
xscrollcommand=self.scrollX.set,
height=h)
line = LinePlotter(desc, canvas, line_data.desc, line_data.box)
line.plot()
canvas.grid(row=row_idx, column=1, sticky=tkinter.W)
self.canvases.append(canvas)
self.set_scroll_bar()
self.pack(expand=True, fill=tkinter.X)
l1 = LineData("L1", (50, 60))
l2 = LineData("L2", (200, 250))
root = tkinter.Tk()
Plotter(root, [l1, l2]).initUI()
root.mainloop()
当我在initUI
设置h = None
时,我看到对象正在扩展到整个窗口
当我将h = 10
设置h = 10
,我看到行越来越细,但它们一直分布在屏幕上。
当我设置h = 50
,我只看到第一行。
理想情况下,我希望看到类似h = 10
但在另一行下面一行的内容。
我该如何实现?
1楼
您的问题是, h
在创建画布时代表像素,但是在配置标签时却代表行数。
用于一个或另一个,但不能同时使用。
假设您希望画布的高度为10像素,只需从标签上除去高度即可。 这将使标签尽可能小。 它将仍然高于10像素,但是您可以通过选择较小的字体来解决该问题。
当我简单地从标签上删除height=h
,我得到的结果是: