Ga Mmeeu
Ga Mmeeu

Reputation: 325

TKinter Geometry Manager displaying multiple rows of widgets

I wish to display a list of sentences with missing words. The basic, one-line, idea is the following: One line example

The construction of the above is a "label + entry + label + spacing + label". In order to make sure that the widgets were aligned left, I used the following code:

phraseLabel1 = tk.Label(questionFrame)
phraseLabel1.pack(side=tk.LEFT)

keyWordEntry = tk.Entry(questionFrame)
keyWordEntry.pack(side=tk.LEFT)

phraseLabel2 = tk.Label(questionFrame)
phraseLabel2.pack(side=tk.LEFT)

keyWordLabel = tk.Label(questionFrame)
keyWordLabel.pack(side=tk.LEFT,padx=30) 

My objective is to present the users with an input screen for multiple sentence. As for example given in the following drawing:

Example multiple lines

Whilst I manage to create the labels via the underneath (experimental) code, I lack understanding to manage the geometry.

root = tk.Tk()
root.title("myTest")
root.geometry("700x700")

questionFrame = tk.Frame(root)
resultFrame = tk.Frame(root)

for frame in (questionFrame, resultFrame):
     frame.grid(row=0, column=0, sticky='news')

#DB Query returning a set of phrases and Keywords
(zinPhrase1, zinPhrase2, keyWordFR, keyWordNL)=getPhrase() 

#Init 
lab1 = []
keyWordEntry = []
lab2 = []
keyWord = []


for i in range(4): #4 is entered as a dummy value

    lab1.append(tk.Label(questionFrame))    
    lab1[i].pack()

    keyWordEntry.append(tk.Entry(questionFrame))
    keyWordEntry[i].pack()

    lab2.append(tk.Label(questionFrame))    
    lab2[i].pack()

    keyWord.append(tk.Label(questionFrame))
    keyWord[i].pack()

    lab1[i].config(text=zinPhrase1[i])
    keyWordEntry[i].config(width=8)
    lab2[i].config(text=zinPhrase2[i])
    keyWord[i].config(text=keyWordNL[i],fg="red")

questionFrame.tkraise()
root.mainloop()

How can I manage the placement of the widgets line by line, as shown in the drawing above? Any help would gratefully appreciated.

Upvotes: 3

Views: 1780

Answers (2)

Bryan Oakley
Bryan Oakley

Reputation: 386342

Since you don't seem to want to organize your widgets in a grid, the most common solution to this problem is to create a frame for each row. The frames stack top-to-bottom, and the widgets inside the frame stack left-to-right.

In my experience, GUI code is much easier to visualize when you separate widget creation from widget layout, so I've done that in the following example to hopefully make it easier to comprehend.

for i in range(4): #4 is entered as a dummy value
    rowFrame = tk.Frame(questionFrame)
    rowFrame.pack(side="top", fill="x")

    lab1.append(tk.Label(rowFrame))    
    keyWordEntry.append(tk.Entry(rowFrame))
    lab2.append(tk.Label(rowFrame))    
    keyWord.append(tk.Label(rowFrame))

    lab1[i].pack(side="left")
    keyWordEntry[i].pack(side="left")
    lab2[i].pack(side="left", padx=(0, 40))
    keyWord[i].pack(side="left")

    lab1[i].config(text=zinPhrase1[i])
    keyWordEntry[i].config(width=8)
    lab2[i].config(text=zinPhrase2[i])
    keyWord[i].config(text=keyWordNL[i],fg="red")

The above code results in something like this:

enter image description here

Upvotes: 3

10SecTom
10SecTom

Reputation: 2664

Would something like the following suffice?

for i in range(4): #4 is entered as a dummy value
    frames.append(tk.Frame(questionFrame))
    frames[i].grid(row=i, column=0, stick='W')

for i in range(4):
    lab1.append(tk.Label(frames[i]))
    lab1[i].grid(row=0, column=0)


    keyWordEntry.append(tk.Entry(frames[i]))
    keyWordEntry[i].grid(row=0, column=1)

    lab2.append(tk.Label(frames[i]))
    lab2[i].grid(row=0, column=2)

    keyWord.append(tk.Label(frames[i]))
    keyWord[i].grid(row=0, column=3)

    lab1[i].config(text=zinPhrase1[i])
    keyWordEntry[i].config(width=8)
    lab2[i].config(text=zinPhrase2[i])
    keyWord[i].config(text=keyWordNL[i],fg="red")

enter image description here

Upvotes: 2

Related Questions