2

So I'm new to python(been coding less than a week) and tkinter but I decided to make a simple expense tracker(not yet finished I got stuck on this part) and after I've gotten all the basics I try moving around the widgets(with .place(x,y)) but the program gets messed up any ideas on how to resolve?

code #1 pre .place(x,y)

code #2 after

import tkinter as tk
from tkinter import *

from tkinter import messagebox

root=Tk()
root.geometry("600x600")
root.title("Expense Tracker")
root.resizable(False,False)
root.config(bg="Gray")

def typeentry():
    global type1
    type1=string_type.get()
    if type1 != "":
        listbox1.insert(END,type1)
        entry_type.delete(0,END)
    else:
        messagebox.showwarning(title="Warning",message="Empty Type")

def nameentry():
    global name1
    name1=string_name.get()
    if name1 != "":
        listbox1.insert(END, name1)
        entry_name.delete(0, END)
    else:
        messagebox.showwarning(title="Warning", message="Empty Name")

def priceentry():
    global price1
    price1=string_price.get()
    if price1 != "":
        listbox1.insert(END, price1)
        entry_price.delete(0, END)
    else:
        messagebox.showwarning(title="Warning", message="Empty Price")

def dateentry():
    global date1
    date1=string_date.get()
    if date1 != "":
        listbox1.insert(END, date1)
        entry_type.delete(0, END)
    else:
        messagebox.showwarning(title="Warning", message="Empty Date")

def submit():
    typeentry(), nameentry(), priceentry(), dateentry()


listbox1=Listbox(root,height=20,width=50)
listbox1.pack()

scrollbarbox=tk.Scrollbar(root)
scrollbarbox.pack(side=tk.RIGHT,fill=tk.Y)

typelbl=Label(root,text="Type of Payment",font=("Helvetica",10),width=20)
typelbl.pack()
namelbl=Label(root,text="Name of Payment",font=("Helvetica",10),width=20)
namelbl.pack()
pricelbl=Label(root,text="Amount of Payment",font=("Helvetica",10),width=20)
pricelbl.pack()
datelbl=Label(root,text="Date of Payment",font=("Helvetica",10),width=20)
datelbl.pack()

string_type = StringVar(root)
string_name = StringVar(root)
string_price = StringVar(root)
string_date = StringVar(root)

entry_type = Entry(root, textvariable=string_type)
entry_type.pack()
entry_name = Entry(root, textvariable=string_name)
entry_name.pack()
entry_price = Entry(root, textvariable=string_price)
entry_price.pack()
entry_date = Entry(root, textvariable=string_date)
entry_date.pack()


submitbutton=tk.Button(root,text="Submit Entry",width=10,command=submit)
submitbutton.pack()


root.mainloop()

###################################################################
import tkinter as tk
from tkinter import *
from tkinter import scrolledtext
from tkinter import messagebox
from tkinter.ttk import Progressbar
from tkinter import filedialog
from tkinter import Menu

root=Tk()
root.geometry("750x400")
root.title("Expense Tracker")
root.resizable(False,False)
root.config(bg="Gray")

def typeentry():
    global type1
    type1=string_type.get()
    if type1 != "":
        listbox1.insert(END,type1)
        entry_type.delete(0,END)
    else:
        messagebox.showwarning(title="Warning",message="Empty Type")

def nameentry():
    global name1
    name1=string_name.get()
    if name1 != "":
        listbox1.insert(END, name1)
        entry_name.delete(0, END)
    else:
        messagebox.showwarning(title="Warning", message="Empty Name")

def priceentry():
    global price1
    price1=string_price.get()
    if price1 != "":
        listbox1.insert(END, price1)
        entry_price.delete(0, END)
    else:
        messagebox.showwarning(title="Warning", message="Empty Price")

def dateentry():
    global date1
    date1=string_date.get()
    if date1 != "":
        listbox1.insert(END, date1)
        entry_date.delete(0, END)
    else:
        messagebox.showwarning(title="Warning", message="Empty Date")

def submit():
    typeentry()
    nameentry()
    priceentry()
    dateentry()


listbox1=Listbox(root,height=20,width=50).place(x=400,y=10)


scrollbarbox=tk.Scrollbar(root)
scrollbarbox.pack(side=tk.RIGHT,fill=tk.Y)

typelbl=Label(root,text="Type of Payment",font=("Helvetica",10),width=20).place(x=10,y=10)

namelbl=Label(root,text="Name of Payment",font=("Helvetica",10),width=20).place(x=10,y=60)

pricelbl=Label(root,text="Amount of Payment",font=("Helvetica",10),width=20).place(x=10,y=110)

datelbl=Label(root,text="Date of Payment",font=("Helvetica",10),width=20).place(x=10,y=160)



string_type = StringVar(root)
string_name = StringVar(root)
string_price = StringVar(root)
string_date = StringVar(root)

entry_type = Entry(root, textvariable=string_type).place(x=200,y=10)

entry_name = Entry(root, textvariable=string_name).place(x=200,y=60)

entry_price = Entry(root, textvariable=string_price).place(x=200,y=110)

entry_date = Entry(root, textvariable=string_date).place(x=200,y=160)



submitbutton=tk.Button(root,text="Submit Entry",width=10,command=submit).place(x=10,y=200)

root.mainloop()

Code #1 outputs something along the lines of

Credit
Netflix
25
7/26/22

Code #2 outputs in terminal

Exception in Tkinter callback
Traceback (most recent call last):
  File "X", line 1921, in __call__
    return self.func(*args)
  File "X", line 55, in submit
    typeentry()
  File "X", line 22, in typeentry
    listbox1.insert(END,type1)
AttributeError: 'NoneType' object has no attribute 'insert'
Random Davis
  • 6,662
  • 4
  • 14
  • 24
zix69
  • 31
  • 4
  • can you provide an example of the two outputs and what you mean by messed up? –  Jul 26 '22 at 16:57
  • @SembeiNorimaki just added both cases to the post :D – zix69 Jul 26 '22 at 17:05
  • 3
    `listbox1=Listbox(..).place(...)` is wrong; `.place()` returns nothing, meaning that `listbox1` is `None`. You need to store the result of `Listbox(..)` first, then call `place()` on that. Like `listbox1=Listbox(root,height=20,width=50)` followed by `listbox1.place(x=400,y=10)`. – Random Davis Jul 26 '22 at 17:15
  • @RandomDavis thanks alot problem solved! this applies to every widget i assume? – zix69 Jul 26 '22 at 17:40
  • 2
    @zix69 it applies to every such function on tkinter objects; you need to refer to the documentation of each and every function you are using in order to see what the return value is - you assumed wrongly in this case, which will never happen if you don't assume anything in the first place. Generally in tkinter, only the constructors themselves return the actual object they are constructing - like, `Button()` returns a `Button`, but a function like `Button.whatever()` usually will not return anything. – Random Davis Jul 26 '22 at 17:44
  • @RandomDavis got it appreciate the feedback! – zix69 Jul 26 '22 at 17:48

1 Answers1

2

Instead of

listbox1=Listbox(root,height=20,width=50).place(x=400,y=10)

Do

listbox1=Listbox(root,height=20,width=50)
listbox1.place(x=400,y=10)

You first store the Listbox in a variable and then place it. Otherwise you have no chance to store the Listbox into a variable and use it afterwards.

This is true for all tkinter components and all the tkinter placing methods like pack, place and grid. Just look at a piece of your own working code:

listbox1=Listbox(root,height=20,width=50)
listbox1.pack()
Filip Müller
  • 1,096
  • 5
  • 18