Tkinter :如何使条目填充整行并响应窗口调整大小?
在自定义小部件中,如何使条目占据列的整个长度?参见下面的示例,我需要我的自定义小部件的第二个条目(self.ent_txt)来占据整个框架的宽度。
import tkinter as tk
from tkinter import ttk
class MyCustomWidget(ttk.Frame):
def __init__(self, master, title=None, *args, **kwargs):
super().__init__( master, *args, **kwargs)
self.title = title
self.buid_widgets()
return
def buid_widgets(self):
self.main_frm = ttk.Frame(self)
self.main_frm.grid(row=0, column=0, sticky=tk.NSEW)
idx_column = -1
if self.title is not None:
idx_column += 1
ttk.Label(self.main_frm, text=self.title).grid(row=0, column=idx_column)
self.main_frm.columnconfigure((0,1,2), weight=1)
self.main_frm.columnconfigure(3, weight=7)
else:
self.main_frm.columnconfigure((0,1), weight=1)
self.main_frm.columnconfigure(2, weight=8)
self.ent_cod = ttk.Entry(self.main_frm, width=10)
self.ent_cod.grid(row=0, column=idx_column+1)
self.btn_show_dt = ttk.Button(self.main_frm, text='OK')
self.btn_show_dt.grid(row=0, column=idx_column+2)
self.ent_txt = ttk.Entry(self.main_frm)
self.ent_txt.grid(row=0, column=idx_column+3, sticky=tk.EW)
self.main_frm.columnconfigure(idx_column+3, weight=10)
return
if __name__== '__main__':
app = tk.Tk()
app.geometry('600x200')
s = ttk.Style()
s.configure('new.TFrame', background='#7AC5CD')
frm_main = ttk.Frame(app, style='new.TFrame')
frm_main.pack(fill=tk.BOTH, expand=1)
frm_container = ttk.Frame(frm_main)
frm_container.grid(row=0, column=0, sticky=tk.NSEW)
frm_container.columnconfigure(0, weight=1)
frm_container.columnconfigure(1, weight=100)
ttk.Label(frm_container, text='Test0:').grid(row=0, column=0)
ttk.Entry(frm_container).grid(row=0, column=1, sticky=tk.EW)
wd_custom = MyCustomWidget(frm_container, title='Test1:')
wd_custom.grid(row=1, column=0, columnspan=2, sticky=tk.EW)
tk.Text(frm_container).grid(row=2, column=0, columnspan=2)
app.mainloop()
发布于 2022-08-08 18:04:24
一个好的经验法则是,对于每个使用grid
管理子小部件的小部件,总是给予至少一行和一列大于零的权重。
另一个有用的提示是,如果一个小部件只有一个子部件,那么使用pack
比使用grid
更容易,因为您可以在一行代码中使它响应。
因此,我建议您在主代码块中使用pack
而不是grid
来实现frm_container
,这样容器就可以填充它所在的窗口。
frm_container.pack(fill="both", expand=True)
在MyCustomWidget
中也可以为main_frm
做同样的事情,因为它是self
中唯一的直接小部件。
self.main_frm.pack(fill="both", expand=True)
如果您更喜欢在grid
中使用MyCustomWidget
,那么您需要遵循第一个经验规则,并给包含条目小部件的行和列赋予权重。
self.main_frm = ttk.Frame(self)
self.main_frm.grid(row=0, column=0, sticky=tk.NSEW)
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
发布于 2022-08-08 18:25:37
@Bryan Oakley
谢谢你的小费。我使用pack创建了自定义小部件。在应用程序中,我使用网格来构建界面。而且起作用了。见建议修改后的结果:
import tkinter as tk
from tkinter import ttk
class MyCustomWidget(ttk.Frame):
def __init__(self, master, title=None, *args, **kwargs):
super().__init__( master, *args, **kwargs)
self.title = title
self.buid_widgets()
return
def buid_widgets(self):
self.main_frm = ttk.Frame(self)
self.main_frm.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
if self.title is not None:
ttk.Label(self.main_frm, text=self.title).pack(side=tk.LEFT)
self.ent_cod = ttk.Entry(self.main_frm, width=10)
self.ent_cod.pack(side=tk.LEFT, fill=tk.Y)
self.btn_show_dt = ttk.Button(self.main_frm, text='OK')
self.btn_show_dt.pack(side=tk.LEFT)
self.ent_txt = ttk.Entry(self.main_frm)
self.ent_txt.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
return
if __name__== '__main__':
app = tk.Tk()
app.geometry('600x200')
s = ttk.Style()
s.configure('new.TFrame', background='#7AC5CD')
frm_main = ttk.Frame(app, style='new.TFrame')
frm_main.pack(fill=tk.BOTH, expand=1)
frm_main.grid_columnconfigure(0, weight=1)
frm_main.grid_rowconfigure(0, weight=1)
frm_container = ttk.Frame(frm_main)
frm_container.grid(row=0, column=0, sticky=tk.NSEW)
frm_container.columnconfigure(0, weight=1)
frm_container.columnconfigure(1, weight=100)
ttk.Label(frm_container, text='Test0:').grid(row=0, column=0)
ttk.Entry(frm_container).grid(row=0, column=1, sticky=tk.EW)
wd_custom = MyCustomWidget(frm_container, title='Test1:')
wd_custom.grid(row=1, column=0, columnspan=2, sticky=tk.EW)
tk.Text(frm_container).grid(row=2, column=0, columnspan=2, sticky=tk.NSEW)
app.mainloop()
https://stackoverflow.com/questions/73281611
复制相似问题