我在Windows中使用Python 3.11.9。
这是我的最低可验证代码:
import tkinter as tk
class Table(tk.Frame):
def __init__(self, master, header_labels:tuple,*args, **kwargs):
tk.Frame.__init__(self, master, *args, **kwargs)
# configuration for all Labels
# easier to maintain than directly inputting args
self.lbl_cfg = {
'master' : self,
'foreground' : 'blue',
'relief' : 'solid',
'font' : 'Arial 20 bold',
'padx' : 5,
'pady' : 0,
'bd' : 1,
'bg' : 'white',
}
self.headers = []
self.rows = []
for col, lbl in enumerate(header_labels):
self.grid_columnconfigure(col, weight=1)
# make and store header
(header := tk.Label(text=lbl, **self.lbl_cfg)).grid(row=0, column=col, sticky='nswe')
self.headers.append(header)
def add_row(self, desc:str, rate:int, quantity:int, amt:int) -> None:
print('adding a row to table')
self.rows.append([])
for col, lbl in enumerate( ((str(len(self.rows))),desc, rate, quantity, amt) ):
(entry := tk.Label(text=lbl, **self.lbl_cfg)).grid(row=len(self.rows), column=col, sticky='nswe')
self.rows[-1].append(entry)
class Application(tk.Tk):
def __init__(self, title:str="Bill generation", x:int=0, y:int=0, **kwargs):
tk.Tk.__init__(self)
self.title(title)
self.config(**kwargs)
#DEFAULTS
#Fixed Entries
header_labels = ('\u2193','Description','Rate','Quantity','Amt','\u2191')
#KEYBOARD SHORTCUTS
#FONT SETTINGS
self.gui_lbl_look = {
'foreground' : 'black',
'relief' : 'flat',
'font' : 'Arial 18 bold',
'padx' : 0,
'pady' : 0,
'borderwidth': 1,
}
self.gui_btn_look = {
'foreground' : 'red',
'relief' : 'groove',
'font' : 'Arial 18 bold',
'padx' : 0,
'pady' : 0,
}
self.gui_entry_look = {
'foreground' : 'blue',
'font' : 'Arial 18 bold',
'highlightbackground' :"black",
'highlightthickness' : 2,
'highlightcolor' :"blue",
'insertbackground' :"blue",
'insertwidth' :3,
}
self.gui_total_lbl_look = {
'foreground' : 'green',
'relief' : 'solid',
'font' : 'Arial 18 bold',
}
#Text input check
#GUI
#bill number and print button
# Second row
self.second_row_frame=tk.Frame(self)
self.second_row_frame.grid(column=0,row=1,sticky='W',pady=5)
# Goods return field
self.lbl_return=tk.Label(self.second_row_frame,text="GR:",**self.gui_lbl_look)
self.lbl_return.grid(column =0, row =0)
self.return_str=tk.StringVar()
self.return_value=tk.Entry(self.second_row_frame,width=5,textvariable=self.return_str,**self.gui_entry_look)
self.return_value.grid(column=1,row=0,padx=(0,5))
#description field
self.default_txt_for_desc=tk.StringVar()
self.default_txt_for_desc.set("PCS")
self.txt_desc=tk.Entry(self.second_row_frame,width=10,textvariable=self.default_txt_for_desc,**self.gui_entry_look)
self.txt_desc.grid(column=2,row=0)
# rate field
self.lbl_rate=tk.Label(self.second_row_frame,text="Rate:",**self.gui_lbl_look)
self.lbl_rate.grid(column=3,row=0,padx=(5,0))
self.rate_str=tk.StringVar()
self.txt_rate=tk.Entry(self.second_row_frame,width=4,textvariable=self.rate_str,**self.gui_entry_look)
self.txt_rate.grid(column=4,row=0)
# quantity field
self.lbl_qty=tk.Label(self.second_row_frame,text="Qty:",**self.gui_lbl_look)
self.lbl_qty.grid(column=5,row=0,padx=(5,0))
self.qty_str=tk.StringVar()
self.txt_qty=tk.Entry(self.second_row_frame,width=3,textvariable=self.qty_str,**self.gui_entry_look)
self.txt_qty.grid(column=6,row=0)
#Item amount
self.lbl_amt=tk.Label(self.second_row_frame,text="Amount:",**self.gui_lbl_look,bd=1,anchor="e",justify="right")
self.lbl_amt.grid(column=7,row=0,padx=(5,0))
self.txt_amt=tk.Label(self.second_row_frame,text='0',width=5,**self.gui_lbl_look,bd=1,anchor="w",justify="left")
self.txt_amt.grid(column=8,row=0)
#Add to table button
self.btn_add=tk.Button(self.second_row_frame,text="Add",command=self.clicked,**self.gui_btn_look)
self.btn_add.grid(column=9,row=0,padx=5)
# Third row entry Table
self.content_frame=tk.Frame(self,highlightbackground="black",highlightthickness=1)
self.content_frame.grid(column=0,row=2,sticky='news')
self.canvas=tk.Canvas(self.content_frame,bg='sky blue')
scrollbar=tk.Scrollbar(self.content_frame,orient="vertical",command=self.canvas.yview,width=50)
self.canvas.configure(yscrollcommand=scrollbar.set)
self.table_frame=tk.Frame(self.canvas)
self.table_frame.grid(column=0,row=0,sticky='news')
self.table_frame.bind("<Configure>",lambda e:self.canvas.configure(scrollregion=self.canvas.bbox("all")))
self.content_frame.columnconfigure(0,weight=2)
self.content_frame.rowconfigure(0,weight=2)
self.canvas.create_window((0, 0),window=self.table_frame,anchor="nw")
self.frame_id=self.canvas.create_window((0,0),window=self.table_frame,anchor="nw")
self.canvas.grid(row=0,column=0,sticky="nswe")
self.canvas.bind_all("<MouseWheel>",self._on_mousewheel)
scrollbar.grid(row=0,column=1,sticky="ns")
self.table_frame.trial_var=0
self.table = Table(self.table_frame,header_labels)
self.table.grid(row=0,column=0,sticky='nswe')
#virtual keyboard
self.keyboard_frame=tk.Frame(self,highlightbackground="black",highlightthickness=1)
self.keyboard_frame.grid(column=0,row=2,sticky='se',padx=(10,55))
self.info_label=tk.Label(self,text=" New bill:space \n Cancel:x \n GR:F1 \n Rate:F2 \n Qty:F3 \n Print:F10 ",**self.gui_total_lbl_look)
self.info_label.grid(column=0,row=2,sticky='ne',padx=(10,55))
self.grid_rowconfigure(2, weight=1)
self.grid_columnconfigure(2, weight=1)
for numbers in range(1,11):
self.add_number_button=tk.Button(self.keyboard_frame,text=str(numbers%10),**self.gui_btn_look)
self.add_number_button.grid(column=int(numbers-1)%3,row=int((numbers-1)/3))
self.clear_button=tk.Button(self.keyboard_frame,text='Del',**self.gui_btn_look)
self.clear_button.grid(column=1,row=3,columnspan=2,sticky='e')
self.enter_button=tk.Button(self.keyboard_frame,text='Enter',**self.gui_btn_look)
self.enter_button.grid(column=0,row=4,columnspan=3,sticky='')
#maximizing table cell
self.grid_columnconfigure(0, weight=1)
#Total quantity amount and balance
self.totals_frame=tk.Frame(self)
self.totals_frame.grid(column=0,row=3,sticky='')
self.lbl_tot_qty=tk.Label(self.totals_frame,text="Total Quantity:",**self.gui_total_lbl_look)
self.lbl_tot_qty.grid(column=0,row=0,padx=5)
self.lbl_tot_amt=tk.Label(self.totals_frame,text="Total Amount:",**self.gui_total_lbl_look)
self.lbl_tot_amt.grid(column=1,row=0,padx=5)
self.lbl_bal=tk.Label(self.totals_frame,text="Balance:",**self.gui_total_lbl_look)
self.lbl_bal.grid(column=2,row=0,padx=5)
# update so we can get the current dimensions
self.update_idletasks()
self.state('zoomed')
#FOR LINUX self.attributes('-zoomed',True)
# test
def _on_mousewheel(self,event):
print('scroll in table')
self.canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")
def clicked(self):
text_qty=(self.txt_qty.get()).lstrip('0')
text_rate=(self.txt_rate.get()).lstrip('0')
item_amt=int(text_rate)*int(text_qty)
print('adding to table')
desc=self.txt_desc.get().upper()
self.table.add_row(desc,int(text_rate),int(text_qty),item_amt)
return
if __name__ == "__main__":
Application(title="Bill printing app").mainloop()
在此代码中,当您在 GR 、费率和数量条目中输入数字,然后按添加按钮,则会将一行添加到表中。
现在我的问题是,当行数超过屏幕并且我们向下滚动时,我希望表格标题(描述、费率数量、amt)应保留在其位置。
你能帮我吗?
我已经尝试发布相关代码,您可以轻松地在您的终端上运行。
如果您需要任何其他详细信息,请告诉我。
谢谢。
您不能将标题放在滚动的画布上方的不同框架中吗?当您滚动浏览表格内容时,这应该使表格标题保持在适当的位置。