tkinter.Frame.Grid调整大小无法正确显示 [英] tkinter.Frame.Grid sizing not displaying correctly
问题描述
您好,我正在制作一个带有标题的表,该标题的文本用于命名列,存储数据的单元格并进行滚动.
Hello I am making a table with a header for text to name the columns, cells to store data, and scrolling.
我遇到的问题是我的表格无法正确显示.应该发生的是,标题应该显示在上方,而下方没有其他空间. (除了我添加的小填充),单元格正确显示在标题的正下方.
The problem I'm having is that my Table is not displaying correctly. What should happen is the Headers should display above with no other space below them. (other than the small padding I added) The cells display correctly right below the headers.
滚动将对y方向的单元格起作用.滚动还针对单元格和标题在x方向上起作用.
The scrolling works for the cells in the y direction. The scrolling also works in the x direction for both the cells and headers.
将单元格添加到框架中的函数只需简单地创建,然后使用grid(row,column)添加 标头只有1行,因此不应在其中留空.
The function the adds the cells to the frame simply does a create then add using grid(row, column) The header only has 1 row so the blank space should not be there.
import tkinter as tk
import collections
from enum import Enum
window = tk.Tk() # Root (main) window
def main():
window.title('Table')
window.geometry("1024x600")
window.update_idletasks()
table_frame = tk.Frame(window, background='black')
table_frame.pack(fill='x')
table = Table(table_frame, 30, 15)
print(id(table))
window.mainloop()
class Table:
def __init__(self, frame, rowCount, columnCount):
self._rowCount = rowCount
self._columnCount = columnCount
main_frame = tk.Frame(frame, bg='blue')
main_frame.pack(fill='both')
self._headerCanvas = tk.Canvas(main_frame)
self._headerCanvas.grid(row=0, column=0, pady=1, sticky='ew')
self._cellCanvas = tk.Canvas(main_frame)
self._cellCanvas.grid(row=1, column=0, sticky='ew')
scroll_bar_y = tk.Scrollbar(main_frame, orient=tk.VERTICAL, command=self._cellCanvas.yview)
scroll_bar_y.grid(row=1, column=1, padx=1, sticky='ns')
scroll_bar_x = tk.Scrollbar(main_frame, orient=tk.HORIZONTAL, command=self.xViewScroll)
scroll_bar_x.grid(row=2, column=0, pady=1, sticky='ew')
main_frame.grid_columnconfigure(0, weight=1)
main_frame.grid_rowconfigure(1, weight=1)
self._cellCanvas.configure(xscrollcommand=scroll_bar_x.set, yscrollcommand=scroll_bar_y.set) #, width=(main_frame.winfo_width()-scroll_bar_y.winfo_width()))
header_frame = tk.Frame(self._headerCanvas)
self._headers = Table.ColumnHeaders(header_frame, self._columnCount)
cell_frame = tk.Frame(self._cellCanvas)
self._cells = Table.Cells(cell_frame, self._rowCount, self._columnCount)
self._headerCanvas.create_window(0, 0, window=header_frame, anchor='nw')
self._headerCanvas.update_idletasks()
self._cellCanvas.create_window(0, 0, window=cell_frame, anchor='nw')
self._cellCanvas.update_idletasks()
self._headerCanvas.configure(scrollregion=self._cellCanvas.bbox("all"))
self._cellCanvas.configure(scrollregion=self._cellCanvas.bbox("all"))
def xViewScroll(self, *args):
self._headerCanvas.xview(*args)
self._cellCanvas.xview(*args)
class Cells:
class Types(Enum):
Entry = 0
Button = 1
class Cell:
def __init__(self, widget, text=''):
self._text = text
self._widget = widget
def getWidget(self):
return self._widget
def setWidget(self, widget):
self._widget = widget
widget = property(getWidget, setWidget, "Get and set the widget of a cell.")
def __init__(self, frame, rows, columns, cellTypes=Types.Entry):
self._cells = [[],[]]
for r in range(rows):
self._cells.append([])
for c in range(columns):
self._cells[r].append(c)
if cellTypes == Table.Cells.Types.Entry:
self._cells[r][c] = Table.Cells.Cell(tk.Entry(frame, width=15))
elif cellTypes == Table.Cells.Types.Button:
self._cells[r][c] = Table.Cells.Cell(tk.Button(frame, width=12))
self._cells[r][c].widget.grid(row=r, column=c)
def getCell(self, row, column):
return self._cells[row][column]
def setCell(self, row, column, cell):
self._cells[row][column] = cell
cells = property(getCell, setCell, "Get and set a cell in the table.")
class ColumnHeaders:
def __init__(self, widget, columnCount):
self._widget = widget
self._columnCount = columnCount
self._headers = Table.Cells(self._widget, 1, self._columnCount, cellTypes=Table.Cells.Types.Button)
main()
这是他们当前的显示方式.
This is how they are currently showing up.
调整屏幕大小后,这就是原始图像的样子.标题位于上方的单元格下方,仅具有填充空间.
After re sizing the screen this is what the original should look like. With the headers just above the cells below with only the padding space.
如果我再缩小一点,则会导致另一个问题,滚动条和标题从视图中消失. 但是,右侧的滚动条永远不会消失. (我猜这是因为我无法再缩小屏幕了.
If I shrink it a little more it causes another problem the scrollbar and the headers disappear from view. The scrollbar on the right never disappears however. ( I'm guessing this is because I can't shrink the screen anymore.
这是main_frame.grid_rowconfigure(1,weight = 1)发生的情况 将其调整为较小的窗口后,将导致此情况.
This is what happens with main_frame.grid_rowconfigure(1, weight=1) It causes this after resizes to a smaller window.
推荐答案
问题:
Frame
网格大小显示不正确
Question:
Frame
Grid sizing not displaying correctly
您被误导了,header_frame
并非使用.grid(...)
进行布局.
使用.create_window(...
将小部件添加到Canvas
的固定位置0, 0, anchor='nw'
.因此,发生否 网格布局管理器" 魔术,如自动调整大小.
You are misguided, the header_frame
is not layouted using .grid(...)
.
Using .create_window(...
add the widget to the Canvas
at the fixed position 0, 0, anchor='nw'
. Therefore, no "Grid Layout Manager" magic, like auto resizing, happens.
为什么要获得此版式?
注意:main_frame == 'blue'
,_headerCanvas == 'lightgreen'
,_cellCanvas == 'red'
:
Why do you get this Layout?
Note: main_frame == 'blue'
, _headerCanvas == 'lightgreen'
, _cellCanvas == 'red'
:
布局: nbsp; bsp 布局:B nbsp; b C nbsp; bsp 布局:D
Layout: A Layout: B Layout: C Layout: D
self._headerCanvas = tk.Canvas(main_frame, bg='lightgreen')
self._headerCanvas.grid(row=0, column=0, pady=1, sticky='ew')
main_frame.grid_rowconfigure(1, weight=1)
self._cellCanvas = tk.Canvas(main_frame, bg='red')
self._cellCanvas.grid(row=1, column=0, sticky='ew')
布局:A :
使用默认的height
创建两个Canvas
.因此,您可以使用网格布局管理器" 获得类似的布局.
Layout: A:
You create both Canvas
with the default height
. Therefore you get a similar layout using "The Grid Layout Manager".
布局:B :
将Itmes添加到Canvas
(此处为单元格Frame
)不会更改布局中的任何内容.
Layout: B:
Adding itmes to a Canvas
, here the Cells Frame
, does not change anything at the Layout.
布局:C :
将Canvas height
与header_frame height
结果同步.
-
使用
.bind('<Configure>'
header_frame = tk.Frame(self._headerCanvas)
header_frame.bind('<Configure>', self.on_configure)
def on_configure(self, event):
# Sync _headerCanvas height with header_frame height
w = event.widget
self._headerCanvas.configure(height=w.winfo_height())
使用.update_idletask()
header_frame = tk.Frame(self._headerCanvas)
self._headers = Table.ColumnHeaders(header_frame, self._columnCount)
root.update_idletasks()
self._headerCanvas.configure(height=header_frame.winfo_height())
仍然不是您想要的吗?
布局:D :
您已通过以下操作使.grid(row=1
尽可能增长:
Still not what you want?
Layout: D:
You have allowed the .grid(row=1
to grow as much as possible by doing:
main_frame.grid_rowconfigure(1, weight=1)
但是您不允许Canvas
使用sticky='ns'
增长.这导致在'blue'
上方/下方的空间.更改为sticky='nsew'
.
But you don't allow the Canvas
to grow using sticky='ns'
. This result in the 'blue'
space above/bottom. Change to sticky='nsew'
.
这篇关于tkinter.Frame.Grid调整大小无法正确显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!