Cześć,
mam widok w zasadzie identyczny z tym:
http://www.java2s.com/Code/Python/GUI-Tk/2dtableofinputfields.htm
z małą zmianą, że wyliczam długość tekstu w kontrolkach (kontrolki są readonly, a zawartość jest znana przy budowaniu okna) i szerokość wszystkich kontrolek w kolumnie ustawiam na szerokość najdłuższej z nich (tak by każda pomieściła tekst). Zatem w zależności od danych tabela może mieć szerokość od 1000 po 1500 (załóżmy).
Jako, że liczba wierszy jest nieznana i może być duża chciałem zrobić scrolla. Zrobiłem to tym kodem:
def myfunction(event):
canvas.configure(scrollregion=canvas.bbox("all"),width=1400,height=700)
tk.Entry(root).grid(sticky='we')
root.grid_columnconfigure(0, weight=1)
myframe=tk.Frame(root,relief=tk.GROOVE,width=600,height=400,bd=1)
myframe.place(x=0,y=0)
canvas=tk.Canvas(myframe)
frame=tk.Frame(canvas)
myscrollbar=tk.Scrollbar(myframe,orient="vertical",command=canvas.yview)
myscrollbar.pack(side="right",fill="y")
canvas.pack(side="left")
canvas.create_window((0,0),window=frame,anchor='nw')
frame.bind("<Configure>",myfunction)
zmieniając następnie też
e = Entry(frame, borderwidth=0, relief=RIDGE, width=maxWidths[j])
Jedyny problem jak sprawić, żeby:
- szerokość canvasa na starcie była zawsze równa sumarycznej szerokości kontrolek entry w wierszu
- szerokość okna była też tyle równa + 23px dla suwaka
- wysokość canvasa niech będzie na sztywne ustawiona na to 700 załóżmy
- przy zmianie rozmiaru okna zmieniała się szerokość canvasa oraz proporcjonalnie szerokość wszystkich kontrolek entry
- przycisk był pod tą tabelą (canvasem)
z przyciskiem próbowałem zrobić tak, że w metodzie grid ustawiałem row=ilośćWierszyKontrolekEntry+1, ale przycisk się nie pojawiał. Bez tego zaś jest on na środku okna.
Potrafię to wszystko wyliczyć i wstawić na sztywno, ale nie będzie reagować na zmianę rozmiaru okna, a pewnie da się ro zrobić jakoś bardziej autaomatycznie. Ustawienie zaś "pack" zamiast "grid" przy przycisku zawiesza uruchamiającą się aplikację.
Pełny przykładowy kod:
import tkinter as tk
class Data:
def __init__(self,name,team,ident,date,details):
self.dictionary = {"NAME": name, 'TEAM': team, "IDENTIFIER": ident, "DATE": date, "DETAILS": details}
def getValueForKey(self,key):
return self.dictionary[key]
headers = ["Name", "Team", "Identifier", "Date", "Details"]
maxWidths = [0,0,0,0,0]
mainList = [Data("a","b","c","d","e"),Data("aa","bb","cc","dd","ee"),Data("aaa","bbb","ccc","ddd","eee"),Data("aaaa","bbbb","cccc","dddd","eeee"),
Data("aaaaa", "bbbbb", "ccccc", "ddddd", "eeeee"), Data("aaaaaa","bbbbbb","cccccc","dddddd","eeeeee"),
Data("a","fshaewyaew hfadfhos dfs hsiousdadfsiu ", "c", "d","ewfhsauhfdsu hsdfo iadhsdfos iadfoshadfs oai huadfs adfhsdfsaasdfo aho ")]
for element in mainList:
for i in range(len(headers)):
lengthOfElement = len(element.getValueForKey(headers[i].upper()))
if maxWidths[i] < lengthOfElement:
maxWidths[i] = lengthOfElement
if maxWidths[i] > 50:
maxWidths[i] = 50
root = tk.Tk()
root.geometry("1423x700")
def myfunction(event):
canvas.configure(scrollregion=canvas.bbox("all"),width=1400,height=500)
tk.Entry(root).grid(sticky='we')
root.grid_columnconfigure(0, weight=1)
myframe=tk.Frame(root,relief=tk.GROOVE,width=600,height=400,bd=1)
myframe.place(x=0,y=0)
canvas=tk.Canvas(myframe)
frame=tk.Frame(canvas)
myscrollbar=tk.Scrollbar(myframe,orient="vertical",command=canvas.yview)
myscrollbar.pack(side="right",fill="y")
canvas.pack(side="left")
canvas.create_window((0,0),window=frame,anchor='nw')
frame.bind("<Configure>",myfunction)
def callback(event):
print(event.widget.grid_info()["row"])
rows = []
for i in range(len(mainList)+1):
cols = []
for j in range(len(headers)):
if i == 0:
control = tk.Label(frame, text=headers[j])
control.grid(row = i, column = j)
else:
control = tk.Entry(frame, borderwidth=0, relief=tk.RIDGE, width=maxWidths[j]+1)
control.grid(row=i, column=j, sticky=tk.NSEW)
control.insert(tk.END, mainList[i-1].getValueForKey(headers[j].upper()))
control.bind("<Button-1>",callback)
control.config(state="readonly")
cols.append(control)
rows.append(cols)
def onPress():
print("something")
tk.Button(text='Get details', command=onPress).grid()
tk.mainloop()