【发布时间】:2021-07-29 07:15:48
【问题描述】:
我正在编写一个简单的电子表格查看器。我想要的是第 0 行是控件而不是滚动,第 1 行是列标题并与数据一起水平滚动,第 2 行到末尾 -1 是数据,并且水平和垂直滚动以及远处的滚动条右,最后一行是水平滚动条。我希望程序填满整个窗口。我现在只使用了窗口的左上角四分之一,水平滚动有效但没有数据,也没有垂直滚动条。
import tkinter as tk
from tkinter import messagebox
def NewFrame(parent,d,ro = 0, co = 0, st = "NEWS", w = 1):
fr = tk.Frame(parent, **d)
fr.grid(row=ro,column=co, sticky=st)
fr.grid_columnconfigure(co, weight=w)
fr.grid_rowconfigure(ro, weight=w)
return fr
def NewCanvas(parent,d,ro = 0, co = 0, st = "NEWS", w = 1):
ca = tk.Canvas(parent, **d)
ca.grid(row=ro,column=co, sticky=st)
ca.grid_columnconfigure(co, weight=w)
ca.grid_rowconfigure(ro, weight=w)
return ca
class test:
def __init__(self,root,hxw):
self.hxw=hxw
root.wm_title("Test")
root.configure(bd=2)
root.configure(background="black")
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
root.grid_rowconfigure(1, weight=1)
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
if not self.hxw:
self.hxw='{0:d}x{1:d}+{2:d}+{3:d}'.format(min(940,screen_width),min(560,screen_height),int(screen_width/3),int(screen_height/3))
root.geometry(self.hxw) #Width x Height
root.update()
self.top = root
self.topFrame = NewFrame(self.top, {'height':25, 'background':"blue"}, st="NEW")
tk.Button(self.topFrame, text="Help", command=self.callback4).grid(row=0, column=0, sticky='E')
self.hsFrame = NewFrame(self.top, {'background':"red"}, st="NEW", ro=1)
self.hcanvas = NewCanvas(self.hsFrame, {'background':"green"}, st="NEW")
self.mFrame = NewFrame(self.hcanvas,{})
self.mFrame.bind(
"<Configure>",
lambda e: self.hcanvas.configure(
scrollregion=self.hcanvas.bbox("all")
)
)
self.hcanvas.create_window((0, 0), window=self.mFrame, anchor="nw")
# Create a horizontal scrollbar linked to the canvas.
hsbar = tk.Scrollbar(self.hsFrame, orient=tk.HORIZONTAL, command=self.hcanvas.xview)
hsbar.grid(row=2, column=0, sticky=tk.EW)
self.hcanvas.configure(xscrollcommand=hsbar.set)
self.labelFrame = NewFrame(self.mFrame, {'background':"grey", 'height':25}) #place a frame on the canvas, this frame will hold the child widgets
for col in range(20):
tkl = tk.Label(self.labelFrame, width=20, borderwidth="1", relief="solid", text=("col %d" % (col+1)))
tkl.grid(row=0, column=col, sticky='news')
self.labelFrame.grid_columnconfigure(col,weight=1)
self.vsFrame = NewFrame(self.mFrame, {'background':"yellow"})
self.vcanvas = NewCanvas(self.vsFrame, {'background':"#ff00ff"})
self.botFrame = NewFrame(self.vcanvas, {'background':"orange"}) #place a frame on the canvas, this frame will hold the child widgets
self.botFrame.bind(
"<Configure>",
lambda e: self.vcanvas.configure(
scrollregion=self.vcanvas.bbox("all")
)
)
self.vcanvas.create_window((0, 0), window=self.vsFrame, anchor="nw")
## # Create a vertical scrollbar linked to the canvas.
self.vsbar = tk.Scrollbar(self.vsFrame, orient=tk.VERTICAL, command=self.vcanvas.yview)
self.vsbar.grid(row=0, column=1, sticky=tk.NS)
self.vcanvas.configure(yscrollcommand=self.vsbar.set)
#
# Add 50-by-20 labels to the frame
rows = 50
columns = 20
for i in range(0, rows):
for j in range(0, columns):
tkl = tk.Label(self.botFrame, width=10, borderwidth="1", relief="solid", text=("%d,%d" % (i+1, j+1)))
tkl.grid(row=i, column=j, sticky='news')
self.botFrame.grid_columnconfigure(j, weight=1)
def callback4(self):
print('root', root.winfo_geometry())
print('self.topFrame', self.topFrame.winfo_geometry())
print('self.hsFrame', self.hsFrame.winfo_geometry())
print('self.hcanvas', self.hcanvas.winfo_geometry())
print('self.mFrame', self.mFrame.winfo_geometry())
print('self.labelFrame', self.labelFrame.winfo_geometry())
print('self.vsFrame', self.vsFrame.winfo_geometry())
print('self.vcanvas', self.vcanvas.winfo_geometry())
print('self.botFrame', self.botFrame.winfo_geometry())
print('------------------------------')
messagebox.showinfo(
"help",
"This is help"
)
# Launch the GUI
root = tk.Tk()
test(root,None)
root.mainloop()
【问题讨论】:
-
你的问题是你没有将
rowconfigure或者columnconfigure申请到root -
你不应该在一个小部件 (
self.mFrame) 上调用.grid,如果它的主人是一个Canvas。尝试使用this。它就像一个普通的tkinter.Frame。 -
这是否记录在任何地方?它符合我的经验,但如果可以的话,我更喜欢使用网格。