Anonymous
Попытка заморозить часть области прокрутки в tkinter с помощью Python в Windows
Сообщение
Anonymous » 01 дек 2024, 15:57
Я использую Python 3.11.9 в Windows.
Вот мой минимальный проверяемый код:
Код: Выделить всё
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("",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("",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, Rate и Qty, затем нажимаете кнопку «Добавить», после чего в таблицу добавляется строка.
Теперь моя проблема в том, что когда количество строк превышает экран и мы прокручиваем вниз, я хочу, чтобы заголовки таблицы (описание, количество ставок, количество) оставались на своих местах.
Можете ли вы мне в этом помочь?
Вот снимок экрана, когда полоса прокрутки находится сверху
Вот скриншот, когда полоса прокрутки находится внизу
Я попытался опубликовать соответствующий код, который вы можете легко запустить на своей стороне.
Если вам нужна дополнительная информация, дайте мне знать.
Спасибо.
Подробнее здесь:
https://stackoverflow.com/questions/792 ... in-windows
1733057855
Anonymous
Я использую Python 3.11.9 в Windows. Вот мой минимальный проверяемый код: [code]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("",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("",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() [/code] В этом коде, когда вы вводите числа в записи GR, Rate и Qty, затем нажимаете кнопку «Добавить», после чего в таблицу добавляется строка. Теперь моя проблема в том, что когда количество строк превышает экран и мы прокручиваем вниз, я хочу, чтобы заголовки таблицы (описание, количество ставок, количество) оставались на своих местах. Можете ли вы мне в этом помочь? Вот снимок экрана, когда полоса прокрутки находится сверху [img]https://i.sstatic.net/M6Nx98Ip.png[/img] Вот скриншот, когда полоса прокрутки находится внизу [img]https://i.sstatic.net/pBOBuYJf.png[/img] Я попытался опубликовать соответствующий код, который вы можете легко запустить на своей стороне. Если вам нужна дополнительная информация, дайте мне знать. Спасибо. Подробнее здесь: [url]https://stackoverflow.com/questions/79239802/attempting-to-freeze-a-part-of-scroll-area-in-tkinter-using-python-in-windows[/url]