0

I tried to follow the lesson on databases in this youtube video from freecodecamp. However, when I wrote my code and executed it, an entry box and a label are stuck on top of my button to submit a record. I don't know how to fix this issue.

Using rowconfigure didn't help either and the label is still stuck on top of the submit button.

Also, for every label and button that I add, even if the button's row is smaller than the label's row, the label is displayed before the button in the GUI.

label and entry box on top of button

I have removed all the database elements from my code as they are not relevant to the problem I am facing. Here is my code:

from tkinter import *
 
window = Tk()
window.geometry("400x400")

# Create function to Delete a record
def delete():
    pass

# create submit function
def submit():
    pass
    
# create query function
def query():
    pass

f_name = Entry(window, width=30)
f_name.grid(row=0, column=1, pady=(10, 0))

l_name = Entry(window, width=30)
l_name.grid(row=1, column=1)

address = Entry(window, width=30)
address.grid(row=2, column=1)

city = Entry(window, width=30)
city.grid(row=3, column=1)

province = Entry(window, width=30)
province.grid(row=4, column=1)

p_code = Entry(window, width=30)
p_code.grid(row=5, column=1)

# Create text box label

f_name_label = Label(window, text="First Name")
f_name_label.grid(row=0, column=0, pady=(10, 0))

l_name_label = Label(window, text="Last Name")
l_name_label.grid(row=1, column=0)

address_label = Label(window, text="Street")
address_label.grid(row=2, column=0)

city_label = Label(window, text="City")
city_label.grid(row=3, column=0)

province_label = Label(window, text="Province")
province_label.grid(row=4, column=0)

p_code_label = Label(window, text="Postal Code")
p_code_label.grid(row=5, column=0)

# Create submit button
submit_btn = Button(window, text="Add record to database", command=submit)
submit_btn.grid(rows=6, column=0, columnspan=2, pady=10, padx=10, ipadx=100)

# create a query button
query_btn = Button(window, text="Show Records", command=query)
query_btn.grid(rows=7, column=0, columnspan=2, pady=10, padx=10, ipadx=125)

delete_box = Label(window, text="ID Number")
delete_box.grid(row=8, column=0)

delete_box = Entry(window, width=30)
delete_box.grid(row=8, column=1)

# create a delete button
delete_btn = Button(window, text="Delete Record", command=delete)
delete_btn.grid(rows=9, column=0, columnspan=2, pady=10, padx=10, ipadx=125)

window.mainloop()

What mistake have I made?

Edit: Thanks for the responses. It turns out that it was just a typo (rows instead of row) that caused the problem. But now I am curious to know how did my previous code give that particular output? Shouldn't it have thrown an error saying that rows is an invalid keyword argument? Moreover, when the row parameter was not even given for submit_btn, how was it correctly placed below "Postal Code"? Why exactly was there an overlap of the label, entry and button?

Sriram Srinivasan
  • 650
  • 2
  • 4
  • 14
  • Please provide a [*minimal* reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). I think the database elements in your code are not relevant to the problem you are facing. You can trim your code and also improve your question title. Title suggestion: *Overlapping of label, entry and button*. – Sriram Srinivasan Apr 03 '22 at 07:35
  • if you have two elements on the same place then probably you use the same `row=` in two elements. That's all. Did you check if both elements have the same `row=` ? – furas Apr 03 '22 at 11:29
  • all your problem is typo - you have `rows=` with `s` at the end, but it should be `row=` without `s` – furas Apr 03 '22 at 11:36
  • @Pedrito-Dio as suggested by Furas, the solution to your problem is pretty simple. However, the exact reason for your output is really interesting. It covers some minute details of tkinter which I wasn't aware of. I will soon add that as an answer. (I am adding this comment just to ensure that this question doesn't get closed.) – Sriram Srinivasan Apr 03 '22 at 12:21
  • Yeah thank you for you both. After hours of head scratching I did solve the error. But really the bug is quite interesting, taking note of that and incorporating it on my next code – Pedrito-Dio Apr 04 '22 at 13:44
  • First time asking a question here on stack overflow. Thank you for helping me. – Pedrito-Dio Apr 04 '22 at 13:45
  • @Pedrito-Dio Yeah, the output is indeed confusing at first. I have drafted an answer with a complete explanation for the output you got. I have made a [reopen request](https://stackoverflow.com/help/reopen-questions#:~:text=You%20may%20only%20vote%20to,question%20with%20a%20single%20vote.) with an [edit](https://stackoverflow.com/review/suggested-edits/31451229) to your question. I will post the answer once the question is reopened. – Sriram Srinivasan Apr 05 '22 at 10:32
  • @furas Could you please consider reopening this question after reviewing my [suggested edit](https://stackoverflow.com/review/suggested-edits/31451229)? – Sriram Srinivasan Apr 05 '22 at 15:49
  • @SriramSrinivasan but all problem is typo in `rows=` which should be `row=` - so problem was resolved and there is no reason to open it only for problem with typo. Besides `typo` shouldn't be treated as question. – furas Apr 05 '22 at 16:18
  • @SriramSrinivasan when I see closed question and still want to share some code then I put it on pastebin.org and later put in comment link to this code. This way OP can get your code and we don't have to open it. – furas Apr 05 '22 at 16:22
  • @furas Thanks for letting me know about Pastebin. However, my answer doesn't consist of code alone. It heavily relies on markdown editing because of text formatting, use of images and multiple short code blocks. Even though the question started as a typo, the reason for the wrong output is quite interesting and requires an answer involving some details which I couldn't find anywhere else on StackOverflow or the internet. – Sriram Srinivasan Apr 05 '22 at 17:10
  • @furas In most cases, a typo would just raise a syntax error. But this is a special case where a typo (according to the coder) turns out to be perfectly correct syntactically. This question would also help future readers who want to understand the reason for the incorrect output if they make a similar mistake. – Sriram Srinivasan Apr 05 '22 at 17:32
  • @SriramSrinivasan OK, I voted for reopen (so you could add answer) but it needs more votes. But they may not vote - so maybe the only solution will be to put answer on other portal (like [pastebin.org](https://pastebin.org) and add link in comment. – furas Apr 06 '22 at 06:18
  • @furas Thanks for the vote. I will wait for a day or two for someone else to vote. – Sriram Srinivasan Apr 06 '22 at 07:37
  • @SriramSrinivasan I now provided the last votes needed to approve the edit and reopen the question. However, in general such large edits by someone other than OP are not appreciated because they might have a tendency to accidentally fix problems. In this specific case based on the discussion in the comments I think this is fine. – MegaIng Apr 09 '22 at 14:33
  • @MegaIng Thanks a lot. I was highly interested in this question and did quite some research to understand the output. Really appreciate your effort in reading the comment section (despite it being so long). – Sriram Srinivasan Apr 09 '22 at 14:41

2 Answers2

1

The reason for your output is really interesting and involves some minute details in tkinter.


Key Observations:

After experimenting with your code, I made the following observations:

  1. rows is equivalent to rowspan and columns is equivalent to columnspan
  2. When row is not given in the .grid statement, it is taken to be <index-of-last-occupied-row> + 1. On the other hand, the default value of column is fixed at 0.

Explanation for the Undesired Output:

Let's first figure out which is the last occupied row after p_code_label is added.

p_code_label = Label(window, text="Postal Code")
p_code_label.grid(row=5, column=0)

p_code_label is present in row[5] and it is the last occupied row.

Next, the buttons are displayed using grid as explained below:

# Create submit button
submit_btn = Button(window, text="Add record to database", command=submit)
submit_btn.grid(rows=6, column=0, columnspan=2, pady=10, padx=10, ipadx=100)

In the above grid statement, row has not been given. Therefore, submit_btn is added to row[5+1=6] and spans 6 rows (due to rows=6).

Now, the last occupied row = 6 + (6-1) = 11.

# create a query button
query_btn = Button(window, text="Show Records", command=query)
query_btn.grid(rows=7, column=0, columnspan=2, pady=10, padx=10, ipadx=125)

As row is once again not given above, query_btn is added to row[11+1=12] and spans 7 rows.

Now, the last occupied row = 12 + (7-1) = 18.

Note that even though submit_btn and query_btn span multiple rows, they appear to be spanning only 1 row because none of the rows have been assigned any weights.

delete_box = Label(window, text="ID Number")
delete_box.grid(row=8, column=0)

delete_box = Entry(window, width=30)
delete_box.grid(row=8, column=1)

Unlike the previous two widgets, the above two widgets have been given a row. Thus, they occupy row[8] and are displayed on top of the submit_btn. The button is almost completely covered vertically even though the above two widgets are present in only one of the rows spanned by submit_btn. This is because the rows do not have any weights.

If all the rows spanned by submit_btn are assigned weights and the button is gridded using sticky=NSEW, the output would be as given below:

Output after assigning weights

(The vertical centre of 6 rows would be in between two rows. That's the reason why Add record to database is displayed between row[8] and row[9].)

By now, the reason for the overlap of the label, entry and button should be clear.

For the sake of completion, I will also explain how is delete_btn added.

# create a delete button
delete_btn = Button(window, text="Delete Record", command=delete)
delete_btn.grid(rows=9, column=0, columnspan=2, pady=10, padx=10, ipadx=125)

The above widget is added to row[18+1=19] and spans 9 rows. Thus, the last occupied row = 19 + (9 - 1) = 27.

Sriram Srinivasan
  • 650
  • 2
  • 4
  • 14
0

I did not make any minor changes except to rearrange in order(Label, Entry and Button) for row index (6,7,8,9).

Also, it's bad for putting Entry widget any where before mainloop().

Always start after row=5. Then you can put Entry widget there.

I rearrange code to make readability widgets order..

Code:

delete_box = Label(window, text="ID Number")
delete_box.grid(row=6, column=0)

delete_box = Entry(window, width=30)
delete_box.grid(row=6, column=1)

# Create submit button
submit_btn = Button(window, text="Add record to database", command=submit)
submit_btn.grid(row=7, column=0, columnspan=2, pady=10, padx=10, ipadx=100)

# create a query button
query_btn = Button(window, text="Show Records", command=query)
query_btn.grid(row=8, column=0, columnspan=2, pady=10, padx=10, ipadx=125)

# create a delete button
delete_btn = Button(window, text="Delete Record", command=delete)
delete_btn.grid(row=9, column=0, columnspan=2, pady=10, padx=10, ipadx=125)

window.mainloop()

Screenshot:

(Entry and

toyota Supra
  • 3,181
  • 4
  • 15
  • 19