Tkinter grid method
<p>I'm using Tkinter to create a GUI for my computer science coursework based on steganography. I'm using the <code>.grid()</code> function on the widgets in my window to lay them out, however I can't get this particular part to look how I want it to.</p>

<p>Here's what my GUI currently looks like: <a href="http://imgur.com/LNEZtEL" rel="nofollow">http://imgur.com/LNEZtEL</a>
(or just the part with the error).</p>

<p>I want the remaining characters label to sit directly underneath the text entry box, but for some reason row 4 starts a large way down underneath the box. If I label the GUI with columns and rows anchored north west it looks like this: <a href="http://imgur.com/a/V7dTW" rel="nofollow">http://imgur.com/a/V7dTW</a>.</p>

<p>If I shrink the image box on the left, it looks how I want, however I don't want the image this small: <a href="http://imgur.com/a/0Dudu" rel="nofollow">http://imgur.com/a/0Dudu</a>.</p>

<p>The image box has a rowspan of 2, so what is causing the 4th row to start so low down from the text entry box? Here's roughly what I want the GUI to look like: <a href="http://imgur.com/a/ck04A" rel="nofollow">http://imgur.com/a/ck04A</a>.</p>

<p>Full code:</p>

<pre><code>imageButton = Button(root, text="Add Image", command = add_image)
imageButton.grid(row = 2, columnspan = 2, sticky = W, padx = 30, pady = 20)
steg_widgets.append(imageButton)

image = Image.open("square.jpg")
image = image.resize((250,250))
photo = ImageTk.PhotoImage(image)
pictureLabel = Label(root, image = photo)
pictureLabel.image = photo
pictureLabel.grid(column = 0, row = 3, columnspan = 2, rowspan = 2, padx = 20, pady = (0, 20), sticky = NW)
steg_widgets.append(pictureLabel)

nameLabel = Label(root, text = "Brandon Edwards - OCR Computer Science Coursework 2016/2017")
nameLabel.grid(row = 0, column = 2, columnspan = 2, padx = (0, 20), pady = 10)
steg_widgets.append(nameLabel)

inputTextLabel = Label(root, text = "Enter text:")
inputTextLabel.grid(row = 2, column = 2, sticky = W)
steg_widgets.append(inputTextLabel)

startButton = Button(root, text="Go!", command = start_stega)
startButton.grid(row = 2, column = 2, sticky = E)
steg_widgets.append(startButton)

inputTextBox = Text(root, height = 10, width = 30)
inputTextBox.grid(row = 3, column = 2, sticky = NW)
steg_widgets.append(inputTextBox)

maxCharLabel = Label(root, text = "Remaining characters:")
maxCharLabel.grid(row = 4, column = 2, sticky = NW)
steg_widgets.append(maxCharLabel)

saveButton = Button(root, text="Save Image", command = save_image)
saveButton.grid(row = 2, column = 3, sticky = W)
steg_widgets.append(saveButton)
</code></pre>

<p>I recommend breaking your UI down into logical sections, and laying out each section separately. </p>

<p>For example, you clearly have two distinct sections: the image and button on the left, and the other widgets on the right. Start by creating containers for those two groups:</p>

<pre><code>import Tkinter as tk
...
left_side = tk.Frame(root)
right_side = tk.Frame(root)
</code></pre>

<p>Since they are side-by-side, <code>pack</code> is the simplest way to lay them out:</p>

<pre><code>left_side.pack(side="left", fill="y", expand=False)
right_side.pack(side="right", fill="both", expand=True)
</code></pre>

<p>Next, you can focus on just one side. You can use <code>pack</code> or <code>grid</code>. This uses <code>grid</code> for illustrative purposes:</p>

<pre><code>image = tk.Canvas(left_side, ...)
button = tk.Button(left_side, ...)

left_side.grid_rowconfigure(0, weight=1)
left_side.grid_columnconfigure(0, weight=1)
image.grid(row=0, column=0, sticky="nw")
button.grid(row=1, column=0, sticky="n")
</code></pre>

<p>Finally, work on the right side. Since widgets are stacked top-to-bottom, <code>pack</code> is the natural choice:</p>

<pre><code>l1 = tk.Label(right_side, text="Enter text:")
l2 = tk.Label(right_side, text="Remaining characters")
text = tk.Text(right_side)
l1.pack(side="top", fill="x")
text.pack(side="top", fill="both", expand=True)
l2.pack(side="top", fill="x")
</code></pre>

python tkinter