I am completely new to Tkinter and I am having problems in placing the widgets where I want them to be.
I have been through numerous posts here, but I can't really find a way to solve my problem.
I created a main window and 5 frames to make the problem easier to solve. However, I cannot place them as I would like them to be.
As, in Tkinter, cell's width/height change dynamically with the size of the largest widget, my GUI ends up being a total mess.
I've added an outline to each frame, so it is easy to see what how widgets are being placed.
Ideally, I would like to fix all cells to a value of, let's say 10, and then just play with span commands (pretty much like an excel sheet with fixed width/height set to all cells).
I thought of playing with "weight" but it doesn't do what I need.
Basic functionality:
- button "..." in "Open csv file", should read a csv file, create a listBox and fill it in with the contents of the csv file selected.
- "Show Plot Preview", should display the Matplotlib graph in the frame for the selected element in the listBox.
- "Show summary", should create a textbox with some data from the csv. For example, min, max, average, etc
- "Save Plots" should enable the "entry" widget and allow the user to select where to save the images.
By the end, the user can say if he wants to plot, preview and save the plots. It should be allowed any combination.
Do you have any ideas? You can change the layout as you wish.
I could not attach text files, so I had to paste the code here. Sorry for that!
Thanks in advance.
Best regards,
Pedro
My horrible layout!
CSV file example
gmId_n,vgs_n,Vth_n,Vov_n,Ids_n,Id_n
24.43,2.50E-02,9.37E-01,-9.12E-01,9.49E-15,9.93E-15
24.43,5.00E-02,9.37E-01,-8.87E-01,2.82E-14,2.91E-14
24.42,7.50E-02,9.37E-01,-8.62E-01,6.34E-14,6.47E-14
24.42,1.00E-01,9.36E-01,-8.36E-01,1.29E-13,1.31E-13
24.42,1.25E-01,9.36E-01,-8.11E-01,2.53E-13,2.55E-13
24.41,1.50E-01,9.36E-01,-7.86E-01,4.86E-13,4.89E-13
24.41,1.75E-01,9.35E-01,-7.60E-01,9.27E-13,9.30E-13
# tkinter libraries
import tkinter as tk, tkinter.ttk as ttk
from tkinter import filedialog
# Data science related libraries
import pandas as pd
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import numpy as np
# OS related library -> functions used - askopenfilename(), askdirectory() and environ
import os
'''
Functions:
mainGUI()
importFromMatPlotLib()
listSelectedItem()
chkBtnCB()
populateListBox()
createListBox()
saveFigs()
hideMe()
'''
# ----- Global Variables -----
# ENTRIES
saveImageEntryRow,saveImageEntryCol = 2,1
saveImgEntryColumnSpan=3
csvEntryRow,csvEntryCol = 1,1
csvEntryColumnSpan=3
# BUTTONS
btnSaveImageRow, btnSaveImageCol=2,12
btnCSVfileRow , btnCSVfileCol = 1,12
btnOKRow, btnOKCol = 7,3
btnCancelRow, btnCancelCol=7,4
# FRAMES
frame1Row, frame1Col = 1,0 # Top entry fields with labels and "..." buttons
frame2Row, frame2Col = 1,1 # Checkbuttons
frame3Row, frame3Col = 3,3 # OK and cancel buttons
frame4Row, frame4Col = 2,0 # Matplotlib graphs
frame5Row, frame5Col = 2,1 # Listbox
lst1=[]
sel=0
def importFromMatPlotLib():
global frame4
fig = Figure(figsize=(4, 3), dpi=100)
t = np.arange(0, 3, .01)
fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t))
canvas = FigureCanvasTkAgg(fig, master=frame4) # A tk.DrawingArea.
canvas.draw()
canvas.get_tk_widget().grid(row=0,column=0,sticky='we',padx=2,pady=2)
def listSelectedItem(*args):
global sel
global lst1
sel = lst1.curselection()
print("Selection -> "+str(sel))
def chkBtnCB(buttonID):
global cbVar1,cbVar2,cbVar3,cbVar4
# These checkboxes enable/disable widgets and change GUI layout accordingly -> only one implemented
if (buttonID==1):
print("Button1 enabled !") if cbVar1.get() else print("Button1 disabled !")
elif (buttonID==2):
print("Button2 enabled !") if cbVar2.get() else print("Button2 disabled !") # Should enable/disable the entry field "saveImgEntry"?
elif (buttonID==3):
print("Button3 enabled !") if cbVar3.get() else print("Button3 disabled !")
elif (buttonID==4):
frame4.grid(row=frame4Row,column=frame4Col,sticky='we',padx=2,pady=2) if cbVar4.get() else frame4.grid_remove()
else:
print("Other button pressed!")
def populateListBox():
global lst1
filename = filedialog.askopenfilename(initialdir = os.environ['HOME'],title = "Select file",filetypes = (("csv files","*.csv"),("all files","*.*")))
#filename=str(os.environ['HOME'])+"/gmId_5V.csv"
df=pd.read_csv(filename)
headers=list(df)
csvEntry.delete(0,'end')
csvEntry.insert(0,filename)
for i in headers:
lst1.insert('end', i)
def createListBox():
global lst1,csvEntry,frame5, frame4
# ----- List Box -----
#Objects
lst1 = tk.Listbox(frame5, height=5,selectmode=tk.EXTENDED)
scrollb = tk.Scrollbar(frame5, orient=tk.VERTICAL, command=lst1.yview)
lbl1=tk.Label(frame5, text="Select fields to plot/save", anchor='w')
sizeg=ttk.Sizegrip(frame5)
# Grid
lst1.grid(column=1, row=5, sticky='ns',columnspan=2)
scrollb.grid(column=3, row=5, sticky='ns')
lbl1.grid(column=1, row=3, sticky='we')
frame5.grid_columnconfigure(1, weight=1)
frame5.grid_rowconfigure(2, weight=1)
lst1['yscrollcommand'] = scrollb.set
# Binding
lst1.bind('<<ListboxSelect>>',listSelectedItem)
frame5.grid(row=2,column=1,sticky='we',padx=2,pady=2)
populateListBox()
def saveFigs():
global lst1,saveImgEntry
dirName = filedialog.askdirectory()
# Update textbox - entry
saveImgEntry.delete(0,'end')
saveImgEntry.insert(0,dirName)
def hideMe():
global mw,saveImgEntry,csvEntry,frame1
if radioVar.get()=='yes':
saveImgEntry=tk.Entry(frame1,state=tk.NORMAL)
saveImgEntry.grid(row=saveImageEntryRow, column=saveImageEntryCol,sticky='we',padx=2,pady=2,columnspan=saveImgEntryColumnSpan)
else:
saveImgEntry=frame1.Entry(mw,state=tk.DISABLED)
saveImgEntry.grid(row=saveImageEntryRow, column=saveImageEntryCol,sticky='we',padx=2,pady=2,columnspan=saveImgEntryColumnSpan)
def mainGUI():
global mw,csvEntry, saveImgEntry, frame4, frame5
mw = tk.Tk()
mw.title("Plotty")
mw.resizable(False, False)
frame1=tk.Frame(mw,bd=2,relief='groove')
frame2=tk.Frame(mw,bd=2,relief='groove')
frame3=tk.Frame(mw,bd=2,relief='groove')
frame4=tk.Frame(mw,bd=2,relief='groove')
frame5=tk.Frame(mw,bd=2,relief='groove',height=300)
frame5.grid_propagate(False)
# LABELS
tk.Label(mw,text="Main Window").grid(row=0,column=0,sticky='ew',columnspan=5)
lbl1=tk.Label(frame1,text="Open csv file:")
lbl2=tk.Label(frame1,text="Save plots:")
# TEXT ENTRIES
global saveImgEntry
csvEntry=tk.Entry(frame1,width=30)
saveImgEntry=tk.Entry(frame1,state=tk.DISABLED,width=30)
# BUTTONS
btnCSVfile=tk.Button(frame1,text="...",command=createListBox)
btnSaveImage=tk.Button(frame1,text="...", command=saveFigs)
btnOK=tk.Button(frame3, text="OK", width=6)
btnCancel=tk.Button(frame3, text="Cancel", width=6, command=mw.destroy)
# CHECK BUTTONS
global cbVar1,cbVar2,cbVar3,cbVar4
cbVar1 = tk.BooleanVar()
cbVar2 = tk.BooleanVar()
cbVar3 = tk.BooleanVar()
cbVar4 = tk.BooleanVar()
chkBtn1=tk.Checkbutton(frame2,text='Display Plots',variable=cbVar1,command= lambda: chkBtnCB(1))
chkBtn2=tk.Checkbutton(frame2,text='Save Plots',variable=cbVar2,command= lambda: chkBtnCB(2))
chkBtn3=tk.Checkbutton(frame2,text='Show Summary',variable=cbVar3,command= lambda: chkBtnCB(3))
chkBtn4=tk.Checkbutton(frame2,text='Show Plot Preview',variable=cbVar4,command= lambda: chkBtnCB(4))
# ------ OBJECTS PLACEMENT IN THE GRID -----
# LABELS
lbl1.grid(row=1,column=0,sticky='w',padx=2,pady=2)
lbl2.grid(row=2,column=0,sticky='w',padx=2,pady=2)
# TEXT ENTRIES
csvEntry.grid(row=csvEntryRow, column=csvEntryCol,sticky='we',padx=2,pady=2,columnspan=csvEntryColumnSpan)
saveImgEntry.grid(row=saveImageEntryRow, column=saveImageEntryCol,sticky='we',padx=2,pady=2,columnspan=saveImgEntryColumnSpan)
# BUTTONS
btnCSVfile.grid(row=1,column=5,sticky='w',padx=2,pady=2)
btnSaveImage.grid(row=2,column=5,sticky='w',padx=2,pady=2)
btnOK.grid(row=3,column=4,sticky='e',padx=2,pady=2)
btnCancel.grid(row=3,column=5,sticky='w',padx=2,pady=2)
# CHECK BUTTONS
chkBtn1.grid(row=0,column=1,sticky='w',columnspan=1,padx=2,pady=2)
chkBtn2.grid(row=1,column=1,sticky='w',columnspan=1,padx=2,pady=2)
chkBtn3.grid(row=0,column=2,sticky='w',columnspan=1,padx=2,pady=2)
chkBtn4.grid(row=1,column=2,sticky='w',columnspan=1,padx=2,pady=2)
importFromMatPlotLib() # Genates a matplotlib plot and places it in frame4
# FRAMES
frame1.grid(row=frame1Row,column=frame1Col,padx=2,pady=2)
frame2.grid(row=frame2Row,column=frame2Col,padx=2,pady=2)
frame3.grid(row=frame3Row,column=frame3Col,padx=2,pady=2)
#frame4.grid(row=2,column=0,sticky='we',padx=2,pady=2) -> done by function chkBtnCB()
#frame5.grid(row=2,column=0,sticky='we',padx=2,pady=2) -> done by function createListBox()
mw.mainloop()
mainGUI()
See Question&Answers more detail:
os