[英]Python - Passing a frame containing tkinter widgets into a class
I'm tring to build a scrollable GUI window containing ttk.Entry
and ttk.Label
. 我正在尝试构建一个包含
ttk.Entry
和ttk.Label
的可滚动GUI窗口。
The only way doing so (as noted in many questions here )- is by creating a Canvas
, with a frame that contains all that widgets. 这样做的唯一方法(如此处的许多问题所述)是通过创建一个
Canvas
,其中包含一个包含所有小部件的框架。
So- my goal is to make such class- that gets as a parameter a frame containing all needed widgets, and display it in a window with horizontal and vertical scroll bars ( since I need it in many displays inside my code ). 因此,我的目标是使此类成为一个包含所有所需小部件的框架作为参数,并将其显示在具有水平和垂直滚动条的窗口中(因为我在代码内部的许多显示器中都需要它)。
After coding successfully - I tried to make a class, but it shows only empty green canvas. 成功编码后-我尝试制作一个类,但只显示空的绿色画布。
Any ideas what am I doing wrong? 有什么想法我做错了吗?
import tkinter as tk
from tkinter import ttk
class CanvasWidgets(ttk.Frame):
def __init__(self, master, frame_in, width=100, height=100):
ttk.Frame.__init__(self, master)
self.master = master
self.frame = frame_in
self.width, self.height = width, height
self.build_gui()
def build_gui(self):
self.canvas = tk.Canvas(self.master, self.width, self.height, bg='light green')
# self.frame = ttk.Frame(self.frame_in)
self.frame.bind("<Configure>", self.onFrameConfigure)
self.vsb = tk.Scrollbar(self.frame, orient="vertical", command=self.canvas.yview)
self.hsb = tk.Scrollbar(self.frame, orient="horizontal", command=self.canvas.xview)
self.canvas.configure(yscrollcommand=self.vsb.set, xscrollcommand=self.hsb.set)
self.vsb.grid(row=0, column=1, sticky=tk.N + tk.S + tk.W)
self.hsb.grid(row=1, column=0, sticky=tk.W + tk.N + tk.E)
self.canvas.create_window((4, 4), window=self.frame, anchor="nw")
self.canvas.grid(row=0, column=0)
def onFrameConfigure(self, event):
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
root = tk.Tk()
frame = ttk.Frame(root)
rows, cols = 5, 5
for row in range(rows):
for col in range(cols):
ttk.Label(frame, text=[row, col], relief=tk.SUNKEN, width=5).grid(row=row, column=col, sticky=tk.E)
a = CanvasWidgets(root, frame)
a.grid()
root.mainloop()
The first problem is that you are placing the canvas in master
when it needs to be in self
. 第一个问题是,你是把画布在
master
时,它需要在self
。 Think of the instance of CanvasWindow
as a box in which you are going to put everything else. 将
CanvasWindow
实例视为要在其中放置其他所有内容的框。
The second problem is that, because the frame was created before the canvas, the frame has a lower stacking order than the canvas. 第二个问题是,因为框架是在画布之前创建的,所以框架的堆叠顺序比画布低。 You need to call
lift
on the frame to get it to be above the canvas. 您需要调用框架上的
lift
,使其位于画布上方。
The third problem is that you're putting the scrollbars in frame
. 第三个问题是您要将滚动条放入
frame
。 You can't put them in the inner frame because they control the inner frame. 您不能将它们放在内部框架中,因为它们控制内部框架。 Instead, they also need to be in
self
. 相反,他们还需要保持
self
。 Both the scrollbar and the canvas need to share a common parent. 滚动条和画布都需要共享一个公共父级。
The fourth problem is that the frame isn't a child of the canvas, so it won't be clipped by the borders of the canvas. 第四个问题是框架不是画布的子元素,因此不会被画布的边界剪裁。 It would be better if the
CanvasWidgets
created the frame, and then the caller can get the frame and add widgets to it. 如果
CanvasWidgets
创建了框架,然后调用者可以获取框架并向其添加小部件,那就更好了。
For example: 例如:
a = CanvasWidgets(root)
rows, cols = 5, 5
for row in range(rows):
for col in range(cols):
label = ttk.Label(a.frame, text=[row, col], relief=tk.SUNKEN, width=5)
label.grid(row=row, column=col, sticky=tk.E)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.