【发布时间】:2021-07-15 23:09:27
【问题描述】:
我正在尝试生成任意数量的行,其中每一行在左侧包含一个标签,在右侧包含一个滚动画布。我的代码如下:
import tkinter as tk
class App(tk.Frame):
def __init__(self, root):
super(App, self).__init__(root)
self.root = root
# CREATE OUTER FRAMES #
self.main_frame = MainFrame(root)
self.main_frame.pack(padx=0, pady=0)
self.RowCollection = RowCollection(root, self.main_frame)
self.row_1 = self.RowCollection.row()
self.row_2 = self.RowCollection.row()
self.row_3 = self.RowCollection.row()
def scroll_x(*args):
# link scrollbar to canvas' xviex
self.row_1.canvas.xview(*args)
self.row_2.canvas.xview(*args)
self.row_3.canvas.xview(*args)
self.scrollbar = tk.Scrollbar(self.RowCollection.right_frame, orient=tk.HORIZONTAL)
self.scrollbar.config(command=scroll_x)
self.scrollbar.grid(row=Row.row_count, column=0, sticky='ew')
canvas_1 = self.row_1.canvas
canvas_1.config(xscrollcommand=self.scrollbar.set)
canvas_1.bind('<Configure>', lambda event: canvas_1.configure(scrollregion=canvas_1.bbox('all')))
canvas_2 = self.row_2.canvas
canvas_2.config(xscrollcommand=self.scrollbar.set)
canvas_2.bind('<Configure>', lambda event: canvas_2.configure(scrollregion=canvas_2.bbox('all')))
canvas_3 = self.row_3.canvas
canvas_3.config(xscrollcommand=self.scrollbar.set)
canvas_3.bind('<Configure>', lambda event: canvas_3.configure(scrollregion=canvas_3.bbox('all')))
# WINDOW_WIDTH = 1000
WINDOW_HEIGHT = 700
WINDOW_WIDTH = root.winfo_screenwidth() - 30
root.geometry(f'{WINDOW_WIDTH}x{WINDOW_HEIGHT}+0+0')
self.pack(side="top")
class MainFrame(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master, bg='blue')
class RowCollection:
"""Collection of rows"""
def __init__(self, root, frame):
self.row_list = []
self.root = root
self.frame = frame
self.right_frame = tk.Frame(self.frame, bg='red', width=10000)
self.right_frame.pack(side=tk.RIGHT)
self.left_frame = tk.Frame(self.frame)
self.left_frame.pack(side=tk.LEFT, fill=tk.Y)
def row(self):
row = Row(self)
self.row_list.append(row)
return row
class Row:
"""Every row consists of a label on the left side and a canvas on the right side"""
row_count = 0
label_width = 15
line_weight = 3
line_yoffset = 3
padx = 20
def __init__(self, collection):
self.frame = collection.frame
self.root = collection.root
self.collection = collection
self.canvas = None
self.label = None
self.text = f'Canvas {Row.row_count}'
self.height = 100
self.root.update()
self.label = tk.Label(self.collection.left_frame,
text=self.text,
height=1,
width=Row.label_width,
relief='raised')
self.label.grid(row=Row.row_count, column=0, sticky='ns')
# configure row size to match future canvas height
self.collection.left_frame.grid_rowconfigure(Row.row_count, minsize=self.height)
self.root.update()
self.canvas = tk.Canvas(self.collection.right_frame,
width=self.root.winfo_width() - self.label.winfo_width(),
height=self.height,
bg='white',
highlightthickness=0)
self.canvas.grid(row=Row.row_count, column=0, sticky='ew')
self.root.update()
# draw line
self.line = self.canvas.create_rectangle(self.padx,
self.canvas.winfo_height() - Row.line_yoffset,
self.canvas.winfo_width() - self.padx,
self.canvas.winfo_height() - Row.line_yoffset + Row.line_weight,
fill='#000000', width=0, tags='line')
# Create point at canvas edge to prevent scrolling from removing padding
self.bounding_point = self.canvas.create_rectangle(0, 0, 0, 0, width=0)
self.bounding_point = self.canvas.create_rectangle(self.canvas.winfo_width(), self.canvas.winfo_width(),
self.canvas.winfo_width(), self.canvas.winfo_width(),
width=0)
# set column weight to 1 so it expands
self.collection.right_frame.grid_columnconfigure(0, weight=1)
# config canvas
self.canvas.config(scrollregion=self.canvas.bbox('all'))
Row.row_count += 1
if __name__ == '__main__':
root = tk.Tk()
app = App(root)
root.mainloop()
我创建了一个主框架,有一个左右框架作为子框架。左框架包含标签,右框架包含画布。
我需要有创建非常宽的画布的选项,但是在 3000 左右的某个值之后,增加右框架的宽度选项似乎对画布大小没有影响。这是怎么回事?
此外,我希望标签始终可见,但目前,增加画布大小最终会将标签推到可见性之外。
【问题讨论】:
标签: python tkinter tkinter-canvas tkinter-layout