Related
Currently I have one window that displays two Treeview frames(festo and transformer) that of identical layout. These treeview layout should display different user data from txt files. Hence, the no of Treeview windows are dynamic based on the no txt files in a folder. Is it possible to create/generate multiple pop-up Treeview windows of the same layout upon a button click?
class HomePage(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
self.notebook = ttk.Notebook() # Create a notebook widget
self.add_tab1()
#self.add_tab2()
self.notebook.grid(row=0)
self.notebook.pack(expand=1, fill="both")
def add_tab1(self):
tab1 = tab_one(self.notebook)
self.notebook.add(tab1, text="Home")
def add_tab2(self):
tab2 = ttk.Notebook()
self.notebook.add(tab2, text="Reports")
class data_table(object):
def __init__(self, site, panels_count, tev_count):
self.site = site
self.panels_count = panels_count
self.tev_count = tev_count
class tab_one(Frame):
def __init__(self, *args, **kwargs):
Frame.__init__(self, *args, **kwargs)
# Creating frames on the window/canvas for the first tab
frame_selectfile = tk.LabelFrame(self, text="Step 1: Zip File Extraction ", bd=6) # Frame1 on the window/canvas
frame_selectfile.grid(column=0, row=0, padx=10, pady=10, sticky='NSEW') # Positioning frame1
frame_selectfile.configure(borderwidth=1)
self.grid_columnconfigure(0, weight=1) # Configuring the column for the main window/canvas
self.grid_rowconfigure(0, weight=1) # Configuring the row for the main window/canvas
frame_checkpd = tk.LabelFrame(self, text="Step 2: Check PD ", bd=6) # Frame2 on the window/canvas
frame_checkpd.grid(column=1, row=0, padx=10, pady=10, sticky='NSEW') # Positioning frame2
frame_checkpd.configure(borderwidth=1)
self.grid_columnconfigure(1, weight=1) # Configuring the column for the main window/canvas
self.grid_rowconfigure(1, weight=1) # Configuring the row for the main window/canvas
frame_festo = tk.LabelFrame(self, text="Festo: ", bd=6) # Frame1 on the window/canvas
frame_festo.grid(column=0, row=1, padx=10, pady=10, sticky='NSEW') # Positioning frame1
frame_festo.configure(borderwidth=1)
self.grid_columnconfigure(1, weight=1) # Configuring the column for the main window/canvas
self.grid_rowconfigure(1, weight=1) # Configuring the row for the main window/canvas
frame_transform = tk.LabelFrame(self, text="Transformer: ", bd=6) # Frame1 on the window/canvas
frame_transform.grid(column=1, row=1, padx=10, pady=10, sticky='NSEW') # Positioning frame1
frame_transform.configure(borderwidth=1)
self.grid_columnconfigure(1, weight=1) # Configuring the column for the main window/canvas
self.grid_rowconfigure(1, weight=1) # Configuring the row for the main window/canvas
# Initializing all variables in frame_selectfile
file_ID = tk.StringVar()
file_ID2 = tk.StringVar()
location_id = tk.StringVar()
location_id2 = tk.StringVar()
unzip_status = tk.StringVar()
tmpdir = tempfile.TemporaryDirectory().name
#self.create_dir_ifnot_exist(tmpdir)
zip_filename = tk.StringVar()
site_id = tk.StringVar()
site_id.set("0")
data_table_list = []
file_counter = tk.StringVar()
# Initializing all variables in frame_festo
festo_date_id = tk.StringVar()
festo_job_id = tk.StringVar()
festo_engineer_id = tk.StringVar()
festo_station_id = tk.StringVar()
festo_voltage_id = tk.StringVar()
festo_db_id = tk.StringVar()
festo_pd_id = tk.StringVar()
# Initializing all variables in frame_transform
transform_date_id = tk.StringVar()
transform_job_id = tk.StringVar()
transform_engineer_id = tk.StringVar()
transform_station_id = tk.StringVar()
transform_voltage_id = tk.StringVar()
transform_db_id = tk.StringVar()
transform_pd_id = tk.StringVar()
topframe = tk.LabelFrame(frame_festo, bd=0)
topframe_transform = tk.LabelFrame(frame_transform, bd=0)
middleframe = tk.LabelFrame(frame_selectfile, bd=5)
databaseView = ttk.Treeview(middleframe, selectmode="browse")
#label_filename = tk.Label(frame_selectfile, text=" ", width=10, relief='flat').grid(column=0, row=1, padx=5, pady=5, sticky='NW')
label_filelocation = tk.Label(frame_selectfile, text="File Location:", width=12, relief='flat').grid(column=0, row=0, padx=5, pady=5, sticky='NW')
filename_Entry = tk.Label(frame_selectfile, width=52, textvariable=file_ID)
filename_Entry.grid(column=1, row=0, padx=5, pady=5, sticky='NW')
filename_Entry.configure(state='normal')
filelocation_Entry = tk.Entry(frame_selectfile, width=60, textvariable=location_id)
filelocation_Entry.grid(column=1, row=0, padx=5, pady=5, sticky='W')
filelocation_Entry.configure(background='palegreen', foreground='black')
middleframe2 = tk.LabelFrame(frame_festo, bd=5)
databaseView2 = ttk.Treeview(middleframe2, selectmode="browse")
transform_middle_frame = tk.LabelFrame(frame_transform, bd=5)
transformView = ttk.Treeview(transform_middle_frame, selectmode="browse")
#label_filename2 = tk.Label(topframe, text=" ", width=10, relief='flat').grid(column=0, row=1, padx=5, pady=5, sticky='NW')
#label_filelocation2 = tk.Label(topframe, text="File Location:", width=12, relief='flat').grid(column=0, row=2, padx=5, pady=5, sticky='NW')
label_festo_date_id = tk.Label(topframe, text="Scanned Date:", width=12, relief='flat').grid(column=0, row=0, padx=5, pady=5, sticky='NW')
label_festo_job_id = tk.Label(topframe, text="Job No:", width=12, relief='flat').grid(column=2, row=0, padx=5, pady=5, sticky='NW')
label_festo_engineer_id = tk.Label(topframe, text="Engineer:", width=12, relief='flat').grid(column=4, row=0, padx=5, pady=5, sticky='NW')
label_festo_station_id = tk.Label(topframe, text="Station:", width=12, relief='flat').grid(column=0, row=1, padx=5, pady=5, sticky='W')
label_festo_voltage_id = tk.Label(topframe, text="Operating Voltage(kV):", width=18, relief='flat').grid(column=2, row=1, padx=5, pady=5, sticky='NW')
label_festo_db_id = tk.Label(topframe, text="Max dB:", width=12, relief='flat').grid(column=4, row=1, padx=5, pady=5, sticky='NW')
#label_festo_pd_id = tk.Label(topframe, text="Max PD:", width=12, relief='flat').grid(column=0, row=2, padx=5, pady=5, sticky='NW')
festo_date_id_Entry = tk.Entry(topframe, width=15, textvariable=festo_date_id)
festo_date_id_Entry.grid(column=1, row=0, padx=5, pady=5, sticky='NW')
festo_date_id_Entry.configure(state='normal')
festo_job_id_Entry = tk.Entry(topframe, width=15, textvariable=festo_job_id)
festo_job_id_Entry.grid(column=3, row=0, padx=5, pady=5, sticky='NW')
festo_job_id_Entry.configure(state='normal')
festo_engineer_id_Entry = tk.Entry(topframe, width=15, textvariable=festo_engineer_id)
festo_engineer_id_Entry.grid(column=5, row=0, padx=5, pady=5, sticky='NW')
festo_engineer_id_Entry.configure(state='normal')
festo_station_id_Entry = tk.Entry(topframe, width=15, textvariable=festo_station_id)
festo_station_id_Entry.grid(column=1, row=1, padx=5, pady=5, sticky='NW')
festo_station_id_Entry.configure(state='normal')
festo_voltage_id_Entry = tk.Entry(topframe, width=15, textvariable=festo_voltage_id)
festo_voltage_id_Entry.grid(column=3, row=1, padx=5, pady=5, sticky='NW')
festo_voltage_id_Entry.configure(state='normal')
festo_db_id_Entry = tk.Entry(topframe, width=15, textvariable=festo_db_id)
festo_db_id_Entry.grid(column=5, row=1, padx=5, pady=5, sticky='NW')
festo_db_id_Entry.configure(state='normal')
label_transform_date_id = tk.Label(topframe_transform, text="Scanned Date:", width=12, relief='flat').grid(column=0, row=0, padx=5, pady=5, sticky='NW')
label_transform_job_id = tk.Label(topframe_transform, text="Job No:", width=12, relief='flat').grid(column=2, row=0, padx=5, pady=5, sticky='NW')
label_transform_engineer_id = tk.Label(topframe_transform, text="Engineer:", width=12, relief='flat').grid(column=4, row=0, padx=5, pady=5, sticky='NW')
label_transform_station_id = tk.Label(topframe_transform, text="Station:", width=12, relief='flat').grid(column=0, row=1, padx=5, pady=5, sticky='NW')
label_transform_voltage_id = tk.Label(topframe_transform, text="Operating Voltage(kV):", width=18, relief='flat').grid(column=2, row=1, padx=5, pady=5, sticky='NW')
label_transform_db_id = tk.Label(topframe_transform, text="Max dB:", width=12, relief='flat').grid(column=4, row=1, padx=5, pady=5, sticky='NW')
#label_transform_pd_id = tk.Label(topframe, text="Max PD:", width=12, relief='flat').grid(column=0, row=2, padx=5, pady=5, sticky='NW')
transform_date_id_Entry = tk.Entry(topframe_transform, width=15, textvariable=transform_date_id)
transform_date_id_Entry.grid(column=1, row=0, padx=5, pady=5, sticky='NW')
transform_date_id_Entry.configure(state='normal')
transform_job_id_Entry = tk.Entry(topframe_transform, width=15, textvariable=transform_job_id)
transform_job_id_Entry.grid(column=3, row=0, padx=5, pady=5, sticky='NW')
transform_job_id_Entry.configure(state='normal')
transform_engineer_id_Entry = tk.Entry(topframe_transform, width=15, textvariable=transform_engineer_id)
transform_engineer_id_Entry.grid(column=5, row=0, padx=5, pady=5, sticky='NW')
transform_engineer_id_Entry.configure(state='normal')
transform_station_id_Entry = tk.Entry(topframe_transform, width=15, textvariable=transform_station_id)
transform_station_id_Entry.grid(column=1, row=1, padx=5, pady=5, sticky='NW')
transform_station_id_Entry.configure(state='normal')
transform_voltage_id_Entry = tk.Entry(topframe_transform, width=15, textvariable=transform_voltage_id)
transform_voltage_id_Entry.grid(column=3, row=1, padx=5, pady=5, sticky='NW')
transform_voltage_id_Entry.configure(state='normal')
transform_db_id_Entry = tk.Entry(topframe_transform, width=15, textvariable=transform_db_id)
transform_db_id_Entry.grid(column=5, row=1, padx=5, pady=5, sticky='NW')
transform_db_id_Entry.configure(state='normal')
unzip_status.set("")
label_unzipstatus = tk.Label(frame_selectfile, width=20, relief='flat', textvariable=unzip_status)
label_unzipstatus.grid(column=1, row=5, padx=5, pady=5, sticky='NSEW')
selectzip_button = tk.Button(frame_selectfile, width=20, text="Select Zip File", command=lambda: self.upload_action(location_id, zip_filename, tmpdir))
selectzip_button.grid(column=1, row=3, padx=5, pady=3, ipady=3, sticky='SW')
unzip_button = tk.Button(frame_selectfile, width=20, text="Extract", command=lambda: self.extract_nested_zip(databaseView, data_table_list, location_id.get(), tmpdir, zip_filename, site_id, False))
unzip_button.grid(column=1, row=3, padx=5, pady=3, ipady=3, sticky='NE')
# Creating LabelFrame in frame_unzip
upperframe = tk.LabelFrame(frame_selectfile, bd=0)
frame_selectfile.rowconfigure(0, weight=1)
frame_selectfile.columnconfigure(2, weight=1)
upperframe.grid(column=0, row=6, columnspan=2, sticky='W')
# middleframe = tk.LabelFrame(frame_selectfile, bd=5)
middleframe.configure(borderwidth=1)
frame_selectfile.columnconfigure(2, weight=1)
frame_selectfile.rowconfigure(1, weight=1)
middleframe.grid(column=0, row=7, columnspan=2, sticky="NSEW")
middleframe2.configure(borderwidth=1)
frame_festo.columnconfigure(2, weight=1)
frame_festo.rowconfigure(1, weight=1)
middleframe2.grid(column=0, row=1, columnspan=2, sticky="NSEW")
transform_middle_frame.configure(borderwidth=1)
frame_transform.columnconfigure(2, weight=1)
frame_transform.rowconfigure(1, weight=1)
transform_middle_frame.grid(column=0, row=1, columnspan=2, sticky="NSEW")
# lowerframe = tk.LabelFrame(frame_selectfile, bd=0)
# lowerframe.grid(column=0, row=7)
# frame_selectfile.columnconfigure(2, weight=1)
# frame_selectfile.rowconfigure(2, weight=0)
topframe.configure(borderwidth=1)
frame_festo.columnconfigure(2, weight=1)
frame_festo.rowconfigure(1, weight=1)
topframe.grid(column=0, row=0, columnspan=2, sticky="NSEW")
topframe_transform.configure(borderwidth=1)
frame_transform.columnconfigure(2, weight=1)
frame_transform.rowconfigure(1, weight=1)
topframe_transform.grid(column=0, row=0, columnspan=2, sticky="NSEW")
# Labels in frame_unzip
label18 = tk.Label(upperframe, text="Number of sites:", relief='flat')
label18.grid(column=0, row=0, padx=5, pady=5, sticky='W')
site_Entry = tk.Entry(upperframe, width=45, textvariable=site_id)
site_Entry.grid(column=1, row=0, padx=10, pady=5, sticky='E')
site_Entry.configure(state='normal', background='palegreen', foreground='black')
# Button Widgets in frame_unzip
#unzip_btn = tk.Button(upperframe, width=10, text="Unzip File", command=lambda: Unzip(databaseview))
#unzip_btn.grid(column=2, row=0, padx=0, pady=5, ipady=2, sticky='E')
# label_details = tk.Label(upperframe, text=" ", relief='flat')
# label_details.grid(column=0, row=2, padx=5, pady=0, sticky='W')
# Combobox Widgets in frame_unzip
# initializing treeview in frame_unzip
# databaseView = ttk.Treeview(middleframe, selectmode="browse")
databaseView.columnconfigure(2, weight=1)
databaseView.grid(column=0, row=0, columnspan=2, sticky="NSEW")
databaseView2.columnconfigure(2, weight=1)
databaseView2.grid(column=0, row=0, columnspan=2, sticky="NSEW")
transformView.columnconfigure(2, weight=1)
transformView.grid(column=0, row=0, columnspan=2, sticky="NSEW")
# Creating treeview in frame_unzip
vsb = Scrollbar(middleframe, orient="vertical", command=databaseView.yview())
hsb = Scrollbar(middleframe, orient="horizontal")
vsb = Scrollbar(middleframe2, orient="vertical", command=databaseView2.yview())
hsb = Scrollbar(middleframe2, orient="horizontal")
vsb = Scrollbar(transform_middle_frame, orient="vertical", command=transformView.yview())
hsb = Scrollbar(transform_middle_frame, orient="horizontal")
middleframe.columnconfigure(0, weight=1)
middleframe.rowconfigure(0, weight=1)
databaseView["show"] = "headings"
databaseView["columns"] = ("site", "panels", "tevs")
vsb.configure(command=databaseView.yview)
# hsb.configure(command=databaseView.xview)
vsb.grid(column=1, row=0, sticky="NS")
# hsb.grid(column=0, row=1, sticky="WE")
middleframe2.columnconfigure(0, weight=1)
middleframe2.rowconfigure(0, weight=1)
databaseView2["show"] = "headings"
databaseView2["columns"] = ("num", "name", "component", "location", "phase", "db", "prpd", "pulse", "pd")
vsb.configure(command=databaseView2.yview)
# hsb.configure(command=databaseView.xview)
vsb.grid(column=1, row=0, sticky="NS")
transform_middle_frame.columnconfigure(0, weight=1)
transform_middle_frame.rowconfigure(0, weight=1)
transformView["show"] = "headings"
transformView["columns"] = ("num", "name", "component", "location", "phase", "db", "prpd", "pulse", "pd")
vsb.configure(command=transformView.yview)
# hsb.configure(command=databaseView.xview)
vsb.grid(column=1, row=0, sticky="NS")
# Treeview column headings
databaseView.heading("site", text="Site")
databaseView.column("site", anchor='w', width=250)
databaseView.heading("panels", text="Number of Panels")
databaseView.column("panels", anchor='center', width=100)
databaseView.heading("tevs", text="Number of TEVs")
databaseView.column("tevs", anchor='center', width=100)
# Treeview column headings festo
databaseView2.heading("num", text="Panel")
databaseView2.column("num", anchor='w', width=100)
databaseView2.heading("name", text="Tev")
databaseView2.column("name", anchor='center', width=150)
databaseView2.heading("component", text="Component")
databaseView2.column("component", anchor='center', width=150)
databaseView2.heading("location", text="Sublocation")
databaseView2.column("location", anchor='w', width=100)
databaseView2.heading("phase", text="Phase Ref Lock")
databaseView2.column("phase", anchor='center', width=100)
databaseView2.heading("db", text="dB")
databaseView2.column("db", anchor='center', width=100)
databaseView2.heading("prpd", text="PRPD")
databaseView2.column("prpd", anchor='w', width=100)
databaseView2.heading("pulse", text="Pulse Wave")
databaseView2.column("pulse", anchor='center', width=100)
databaseView2.heading("pd", text="PD%")
databaseView2.column("pd", anchor='center', width=100)
# Treeview column headings transform
transformView.heading("num", text="Panel")
transformView.column("num", anchor='w', width=100)
transformView.heading("name", text="Tev")
transformView.column("name", anchor='center', width=150)
transformView.heading("component", text="Component")
transformView.column("component", anchor='center', width=150)
transformView.heading("location", text="Sublocation")
transformView.column("location", anchor='w', width=100)
transformView.heading("phase", text="Phase Ref Lock")
transformView.column("phase", anchor='center', width=100)
transformView.heading("db", text="dB")
transformView.column("db", anchor='center', width=100)
transformView.heading("prpd", text="PRPD")
transformView.column("prpd", anchor='w', width=100)
transformView.heading("pulse", text="Pulse Wave")
transformView.column("pulse", anchor='center', width=100)
transformView.heading("pd", text="PD%")
transformView.column("pd", anchor='center', width=100)
# Widgets in Frame 3
#label_checkstatus = tk.Label(frame_checkpd, text="Status", width=5, relief='flat').grid(column=2, row=0, padx=5, pady=5, sticky='E')
#label_checkstatuscolour = tk.Label(frame_checkpd, text=" ", bg="limegreen", width=5, relief='flat').grid(column=2, row=1, padx=5, pady=5, sticky='E')
findpd_btn = tk.Button(frame_checkpd, width=20, text="Find PDs", command=lambda: self.run_pd_model_exe(tmpdir, zip_filename))
findpd_btn.grid(column=1, row=1, padx=5, pady=5, sticky='E')
export_pdf_btn = tk.Button(frame_checkpd, width=20, text="Export to PDF",
command=lambda: self.export_to_pdf(tmpdir, zip_filename))
export_pdf_btn.grid(column=2, row=1, padx=5, pady=5, sticky='E')
file_counter = 0
find_files_btn = tk.Button(frame_checkpd, width=20, text="Check Files", command=lambda: self.check_files(file_counter, find_files_btn))
find_files_btn.grid(column=3, row=1, padx=5, pady=5, sticky='NSEW')
print(file_counter)
file_counter = 0
#selectzip_button.grid(column=1, row=3, padx=5, pady=3, ipady=3, sticky='SW')
def check_files(self, counter, btn):
# folder path
dir_path = r'C:\Users\Documents\GUI\input_folder'
count = 0
# Iterate directory
for path in os.listdir(dir_path):
# check if current path is a file
if os.path.isfile(os.path.join(dir_path, path)):
count += 1
print('File count:', count)
return count
The following code
root = tk.Tk()
frame = ttk.Frame(root, padding=10)
frame.grid()
# Browse
tk.Text(frame, state="disabled", height=1).grid(column=0, row=0, columnspan=3, sticky="W", pady=5, ipadx=2, ipady=2)
ttk.Button(frame, text="Browse", command=None).grid(column=3, row=0, sticky="E")
# Selected files
tk.Text(frame, state="disabled").grid(column=0, row=1, columnspan=4, sticky="EW", pady=10)
# Options
ttk.Button(frame, text="SELECT", command=None).grid(column=0, row=2, sticky="W")
ttk.Button(frame, text="DELETE", command=None).grid(column=1, row=2, sticky="W")
ttk.Button(frame, text="Merge", command=None).grid(column=2, row=2, sticky="W")
ttk.Button(frame, text="Close", command=root.destroy).grid(column=3, row=2, sticky="E")
root.mainloop()
produces this,
but I want the DELETE and MERGE buttons to be left-aligned so they are together with the SELECT button. How can I achieve this?
Put buttons in new Frame and this frame put in original Frame
buttons_frame = ttk.Frame(frame)
buttons_frame.grid(column=0, row=2, sticky="W")
ttk.Button(buttons_frame, text="SELECT", command=None).grid(column=0, row=2, sticky="W")
ttk.Button(buttons_frame, text="DELETE", command=None).grid(column=1, row=2, sticky="W")
ttk.Button(buttons_frame, text="Merge", command=None).grid(column=2, row=2, sticky="W")
BTW:
In buttons_frame you may even use .pack(side='left') instead of grid()
Full code:
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
frame = ttk.Frame(root, padding=10)
frame.grid()
# Browse
tk.Text(frame, state="disabled", height=1).grid(column=0, row=0, columnspan=3, sticky="W", pady=5, ipadx=2, ipady=2)
ttk.Button(frame, text="Browse", command=None).grid(column=3, row=0, sticky="E")
# Selected files
tk.Text(frame, state="disabled").grid(column=0, row=1, columnspan=4, sticky="EW", pady=10)
# Options
buttons_frame = ttk.Frame(frame)
buttons_frame.grid(column=0, row=2, sticky="W")
ttk.Button(buttons_frame, text="SELECT", command=None).grid(column=0, row=2, sticky="W")
ttk.Button(buttons_frame, text="DELETE", command=None).grid(column=1, row=2, sticky="W")
ttk.Button(buttons_frame, text="Merge", command=None).grid(column=2, row=2, sticky="W")
ttk.Button(frame, text="Close", command=root.destroy).grid(column=3, row=2, sticky="E")
root.mainloop()
EDIT:
You may also add empy column between Merge and Close and assign weight=1 to this column so it will get all empty space.
It needs to move Browse and Close to next column, and increase columnspan in both Text
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
frame = ttk.Frame(root, padding=10)
frame.grid()
frame.columnconfigure(3, weight=1) # column 3 will use all free space
# Browse
tk.Text(frame, state="disabled", height=1).grid(column=0, row=0, columnspan=4, sticky="W", pady=5, ipadx=2, ipady=2)
ttk.Button(frame, text="Browse", command=None).grid(column=4, row=0, sticky="E")
# Selected files
tk.Text(frame, state="disabled").grid(column=0, row=1, columnspan=5, sticky="EW", pady=10)
# Options
ttk.Button(frame, text="SELECT", command=None).grid(column=0, row=2, sticky="W")
ttk.Button(frame, text="DELETE", command=None).grid(column=1, row=2, sticky="W")
ttk.Button(frame, text="Merge", command=None).grid(column=2, row=2, sticky="W")
ttk.Button(frame, text="Close", command=root.destroy).grid(column=4, row=2, sticky="E")
root.mainloop()
This is my code:
mycanvas = Canvas(self.search_result_frame)
mycanvas.pack(side=LEFT)
yscrollbar = ttk.Scrollbar(self.search_result_frame, orient="vertical", command=mycanvas.yview)
yscrollbar.pack(side=RIGHT, fill=Y)
mycanvas.configure(yscrollcommand=yscrollbar.set)
mycanvas.bind('<Configure>', lambda e: mycanvas.configure(scrollregion = mycanvas.bbox('all')))
self.sample_frame = Frame(mycanvas)
mycanvas.create_window((0,0), window=self.sample_frame, anchor=E)
for widget in self.search_result_frame.winfo_children():
widget.destroy()
if len(matching_bills) > 0:
for bill in matching_bills:
with open(f'{self.bill_folder}//{bill}//data//bill_details.json', 'r') as bill_json_file:
bill_details = json.loads(bill_json_file.read())
customer_name = bill_details["customer_details"][0]
payment_method = bill_details["payment_method"]
date_of_issue = bill_details["date_of_issue"]
date_of_issue = datetime.strptime(date_of_issue, "%d/%m/%Y")
date_of_issue = date_of_issue.strftime("%d %b %Y")
# # -------------------- Search Result Frame Contents
result_frame = Frame(self.sample_frame, bg=self.bg3, bd=5, relief=GROOVE)
result_frame.pack(fill=BOTH, pady=2)
result_billno_lbl = Label(result_frame, text=bill, bg=self.bg1, fg="#FFF", font=self.search_results_font1, padx=22, pady=3)
result_billno_lbl.grid(row=0, column=0, padx=50, pady=8, sticky=W)
billed_to_lbl = Label(result_frame, text=f"Billed To - {customer_name}", bg=self.bg1, fg="#FFF", font=self.search_results_font2, bd=2, relief=RAISED, padx=12, pady=3)
billed_to_lbl.grid(row=0, column=1, padx=80, sticky=W)
billed_type_lbl = Label(result_frame, text=f"Bill Type - {payment_method}", bg=self.bg1, fg="#FFF", font=self.search_results_font2, bd=2, relief=RAISED, padx=12, pady=3)
billed_type_lbl.grid(row=0, column=2, sticky=W)
issued_on_lbl = Label(result_frame, text=f"Issued On - {date_of_issue}", bg=self.bg1, fg="#FFF",
font=self.search_results_font2, bd=2, relief=RAISED, padx=12, pady=3)
issued_on_lbl.grid(row=0, column=3, padx=80, sticky=W)
view_btn = Button(result_frame, text="View", font="Comicsan 14", bd=2, relief=GROOVE, bg="#000", fg="#FFF", padx=1, command=lambda bill=bill: self.view_bill(bill))
view_btn.grid(row=0, column=4, padx=3, columnspan=2, sticky=W)
elif len(matching_bills) == 0:
for widgets in self.search_result_frame.winfo_children():
widgets.destroy()
no_result_lbl = Label(self.search_result_frame, text=f"No search result found for {bill_cat}", font=self.search_results_font1, bg=self.bg3, fg="#FFF")
no_result_lbl.pack(fill=X)
When I run it, it shows me the bad window path name ".!labelframe.!canvas.!frame error and when I try to do the same thing without object-oriented in tkinter then it works well !
I am mainly coding on my MAC.
I created a GUI that is used for a tool I am using to automate things with selenium.
I have used .grid for all widgets in my GUI.
But when I open the GUI on my Windows laptop at home (same resolution but much smaller monitor panel) it is totally messed up.
Here are two screenshot showing the problem,
Messed up layout on Win Laptop (17,3")
The second screenshot shows how it should look.
This is the code I used for the grid layout:
# General GUI settings
app = Tk()
app.title('trade_buddy')
app.geometry('605x800')
app.minsize(605, 800)
app.maxsize(605, 800)
app.grid_rowconfigure(0, weight=1)
app.grid_rowconfigure(1, weight=1)
app.grid_rowconfigure(2, weight=1)
app.grid_rowconfigure(3, weight=1)
app.grid_rowconfigure(4, weight=1)
app.grid_rowconfigure(5, weight=1)
app.grid_rowconfigure(6, weight=1)
app.grid_rowconfigure(7, weight=1)
app.grid_rowconfigure(8, weight=1)
app.grid_rowconfigure(9, weight=1)
app.grid_rowconfigure(10, weight=1)
app.grid_rowconfigure(11, weight=1)
app.grid_rowconfigure(12, weight=1)
app.grid_rowconfigure(13, weight=1)
#Background label
image = Image.open('v2.0/lolo.png')
image = image.resize((600,450), Image.ANTIALIAS)
copy_of_image = image.copy()
photo = ImageTk.PhotoImage(image)
label = tk.Label(app, image = photo)
label.place(x=0, y=0)
#Buttons
b_init = tk.Button(app,text='Initialize',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10, command=lambda:threading.Thread(target=tb,daemon=True).start())
b_exit = tk.Button(app,text='Exit',font='Tahoma 10 bold',padx=8,bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d', pady=10,command=lambda:threading.Thread(target=exit_tb,daemon=True).start())
b_start = tk.Button(app,text='Start',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10,command=lambda:threading.Thread(target=filters,daemon=True).start())
b_pause = tk.Button(app,text='Pause',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10,command=lambda:threading.Thread(target=stop_tb,daemon=True).start())
b_tfm = tk.Button(app,text='TFM',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10,command=lambda:threading.Thread(target=tfm,daemon=True).start())
#Labels
l_maxBO = tk.Label(app,text='Maximum buy price:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
l_itemsontf = tk.Label(text='# of items on transfer list:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
l_speed = tk.Label(text='Choose speed:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10 bold')
l_routine = tk.Label(text='Choose routine:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10 bold')
#Entries
e_maxBO = tk.Entry(app, width=10, bg='#1e1e1f', fg='#f8f09d', font='Tahoma 10')
e_itemsontf = tk.Entry(app, width=10, bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
e_fixedsellprice = tk.Entry(app, width=10, bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
#Text box
t_outputbox = tk.Text(app, width=99, height=27, font='Tahoma 10',bg='#2c2c2c', fg='#f8f09d', relief=SUNKEN, highlightthickness="1")
#Grid Layout
l_maxBO.grid(row=0, column=0, sticky='w', padx=5, pady=5)
l_itemsontf.grid(row=1, column=0, sticky='w', padx=5, pady=5)
l_speed.grid(row=3, column=0, sticky='w', padx=5, pady=1, ipady=1)
l_routine.grid(row=7, column=0, sticky='w', padx=5, pady=1, ipady=1)
e_maxBO.grid(row=0, column=1, sticky='w', padx=5, pady=5)
e_itemsontf.grid(row=1, column=1, sticky='w', padx=5, pady=5)
e_fixedsellprice.grid(row=11, column=0, sticky='w', padx=5, pady=3)
b_exit.grid(row=12, column=8, sticky='sw', padx=5, pady=10)
b_init.grid(row=12, column=4, sticky='sw', padx=5, pady=10)
b_start.grid(row=12, column=0, sticky='sw', padx=5, pady=10)
b_pause.grid(row=12, column=1, sticky='sw', padx=5, pady=10)
b_tfm.grid(row=12, column=2, sticky='sw', padx=5, pady=10)
r_normal.grid(row=4, column=0, sticky='w', padx=5, pady=1)
r_fast.grid(row=5, column=0, sticky='w', padx=5, pady=1)
r_slow.grid(row=6, column=0, sticky='w', padx=5, pady=1)
r_buyonly.grid(row=8, column=0, sticky='w', padx=5, pady=1)
r_fullroutine.grid(row=9, column=0, sticky='w', padx=5, pady=1)
r_buysellfixed.grid(row=10, column=0, sticky='w', padx=5, pady=1)
t_outputbox.grid(row=13, column=0, columnspan=13, rowspan=13, sticky='nsew', padx=5, pady=10)
As a coding beginner, I really have no idea what else I could change.
I already changed from .place to .grid but the problem is still the same.
Does anyone have an idea how I could setup my GUI that it keeps the minimum required geometry relations no matter on what monitor I work?
Here is an example of forcing it to look like the second picture.
import tkinter as tk
from PIL import ImageTk, Image
# General GUI settings
app = tk.Tk()
app.configure(bg="black")
#Background label
image = Image.open('test.png')
image = image.resize((200,200), Image.ANTIALIAS)
copy_of_image = image.copy()
photo = ImageTk.PhotoImage(image)
label = tk.Label(app, image = photo)
label.grid(row=3, column=1, sticky='w')
#others
r_normal = tk.Radiobutton(app, text="Normal Speed")
r_fast = tk.Radiobutton(app, text="Fast Speed")
r_slow = tk.Radiobutton(app, text="Slow Speed")
r_buyonly = tk.Radiobutton(app, text="Buy only")
r_fullroutine = tk.Radiobutton(app, text="Full routine (optimized price)")
r_buysellfixed = tk.Radiobutton(app, text="Buy and sell for fixed price")
#Buttons
b_init = tk.Button(app,text='Initialize',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10, command=lambda:threading.Thread(target=tb,daemon=True).start())
b_exit = tk.Button(app,text='Exit',font='Tahoma 10 bold',padx=8,bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d', pady=10,command=lambda:threading.Thread(target=exit_tb,daemon=True).start())
b_start = tk.Button(app,text='Start',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10,command=lambda:threading.Thread(target=filters,daemon=True).start())
b_pause = tk.Button(app,text='Pause',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10,command=lambda:threading.Thread(target=stop_tb,daemon=True).start())
b_tfm = tk.Button(app,text='TFM',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10,command=lambda:threading.Thread(target=tfm,daemon=True).start())
#Labels
l_maxBO = tk.Label(app,text='Maximum buy price:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
l_itemsontf = tk.Label(text='# of items on transfer list:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
l_speed = tk.Label(text='Choose speed:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10 bold')
l_routine = tk.Label(text='Choose routine:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10 bold')
#Entries
e_maxBO = tk.Entry(app, width=10, bg='#1e1e1f', fg='#f8f09d', font='Tahoma 10')
e_itemsontf = tk.Entry(app, width=10, bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
e_fixedsellprice = tk.Entry(app, width=10, bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
#Text box
t_outputbox = tk.Text(app, width=99, height=27, font='Tahoma 10',bg='#2c2c2c', fg='#f8f09d', relief=tk.SUNKEN, highlightthickness="1")
#Grid Layout
l_maxBO.grid(row=0, column=0, sticky='w', padx=5, pady=5)
l_itemsontf.grid(row=1, column=0, sticky='w', padx=5, pady=5)
l_speed.grid(row=3, column=0, sticky='w', padx=5, pady=1, ipady=1)
l_routine.grid(row=7, column=0, sticky='w', padx=5, pady=1, ipady=1)
e_maxBO.grid(row=0, column=1, sticky='w', padx=5, pady=5)
e_itemsontf.grid(row=1, column=1, sticky='w', padx=5, pady=5)
e_fixedsellprice.grid(row=11, column=0, sticky='w', padx=5, pady=3)
b_exit.grid(row=12, column=8, sticky='sw', padx=5, pady=10)
b_init.grid(row=12, column=4, sticky='sw', padx=5, pady=10)
b_start.grid(row=12, column=0, sticky='sw', padx=5, pady=10)
b_pause.grid(row=12, column=1, sticky='sw', padx=5, pady=10)
b_tfm.grid(row=12, column=2, sticky='sw', padx=5, pady=10)
r_normal.grid(row=4, column=0, sticky='w', padx=5, pady=1)
r_fast.grid(row=5, column=0, sticky='w', padx=5, pady=1)
r_slow.grid(row=6, column=0, sticky='w', padx=5, pady=1)
r_buyonly.grid(row=8, column=0, sticky='w', padx=5, pady=1)
r_fullroutine.grid(row=9, column=0, sticky='w', padx=5, pady=1)
r_buysellfixed.grid(row=10, column=0, sticky='w', padx=5, pady=1)
t_outputbox.grid(row=13, column=0, columnspan=13, rowspan=13, sticky='nsew', padx=5, pady=10)
Notable differences:
I had to set a background color to make up for how we are moving that image.
The image is no longer using .place and instead using .grid.
The image will need to be resized a bit differently because it is a smaller area.
I removed all those row_configures because they were removing some rigidity, you can add it back if you like, but you'll have to re-scale your columns to match the new layout.
Let us know if you have any questions etc.
I have a program that uses Tkinter and I'm trying to assign a command to a button in my root window that opens one additional window. I'm using Toplevel(), but whenever I click the button I've assigned the command to, two windows open, one with my root window's name and one with the name of the additional window I've assigned.
I've tried using .withdraw and .destroy, to hide or remove this extra root window, but nothing seems to be working.
Here is my code:
import Tkinter
from Tkinter import *
root = Tk()
root.wm_title("VACS")
# # Top label # #
SetParameters = Label(text="Set Parameters", width=110, relief=RIDGE)
SetParameters.grid(row=1, column=0, columnspan=7, padx=5, pady=5)
# # Spatial freq settings # #
SpatialFreq = Label(text="Spatial Frequency", width=15, relief=RIDGE)
SpatialFreq.grid(row=3, column=0, padx=5, pady=5)
From1 = Label(text="from")
From1.grid(row=3, column=1, padx=5, pady=5)
Select1 = Spinbox(from_=0, to=10, width=25)
Select1.grid(row=3, column=2, padx=5, pady=5)
To1 = Label(text="to")
To1.grid(row=3, column=3, padx=5, pady=5)
Select2 = Spinbox(from_=0, to=10, width=25)
Select2.grid(row=3, column=4, padx=5, pady=5)
Steps = Label(text="in steps of")
Steps.grid(row=3, column=5, padx=5, pady=5)
Select3 = Spinbox(from_=0, to=10, width=25)
Select3.grid(row=3, column=6, padx=5, pady=5)
# # Contrast settings # #
Contrast = Label(text="Contrast", width=15, relief=RIDGE)
Contrast.grid(row=5, column=0, padx=5, pady=5)
From2 = Label(text="from")
From2.grid(row=5, column=1, padx=5, pady=5)
Select4 = Spinbox(from_=0, to=10, width=25)
Select4.grid(row=5, column=2, padx=5, pady=5)
To2 = Label(text="to")
To2.grid(row=5, column=3, padx=5, pady=5)
Select5 = Spinbox(from_=0, to=10, width=25)
Select5.grid(row=5, column=4, padx=5, pady=5)
Steps2 = Label(text="in steps of")
Steps2.grid(row=5, column=5, padx=5, pady=5)
Select6 = Spinbox(from_=0, to=10, width=25)
Select6.grid(row=5, column=6, padx=5, pady=5)
# # Test button # #
Test = Button(text="Begin Test", width=25, command=Top)
Test.grid(row=6, column=0, columnspan=7, pady=5)
# # Directory input window # #
def Top():
Toplevel()
Toplevel().wm_title("Directory")
root.mainloop()
If you click "Begin Test" in the root window, two extras pop up. I only want the one that says "Directory."
Any ideas?
You're creating two, since Toplevel() is the constructor call:
Toplevel()
Toplevel().wm_title("Directory")
Instead, create one and save it:
top = Toplevel()
top.wm_title("Directory")