1

I want to make a simple household account program using tkinter module in python. I want to bind okclick function to button1. I think I coded appropriate referencing other codes but when I execute this code there happens a message that the function okclick is not defined.

Does anyone know what is wrong with it?

from tkinter import *
from tkinter import ttk
import colors as c
from tkcalendar import DateEntry

b=Tk()

class memo(Frame):

    def __init__(self,master):
        Frame.__init__(self,master)
        self.master=master
        self.master.title('Memo')
        self.pack(fill=BOTH, expand=True)

        frame1=Frame(self,width=500,height=50)
        frame1.pack(expand=False)
        label1=Label(frame1,text='Amount',width=10)
        label1.pack(side=LEFT, padx=10,pady=10)
        entry1=Entry(frame1,width=20)
        entry1.pack(padx=10,fill=X,expand=True)

        frame2=Frame(self,width=500,height=50)
        frame2.pack(expand=False)
        label2=Label(frame2,text='Cartegory',width=10)
        label2.pack(side=LEFT, padx=10,pady=10)
        listbox1=Listbox(frame2,width=20)
        listbox1.insert(END,"식료품비","잡화비","건강관리비","외식비")
        listbox1.pack(side=LEFT, padx=10,pady=10)

        frame3=Frame(self,width=500,height=50)
        frame3.pack(expand=False)
        label3=Label(frame3,text='Date',width=10)
        label3.pack(side=LEFT, padx=10,pady=10)
        dateentry = DateEntry(frame3)
        dateentry.pack(padx=10,pady=10)

        frame4=Frame(self,width=500,height=500)
        frame4.pack(expand=False)
        button1=Button(frame4,text='csv Export',command=self.okClick)
        button1.pack(side=LEFT,padx=10,pady=10)

    def okClick(self):
        name = self.entry1.get()
        print(name)

a=memo(b)
a.mainloop()
martineau
  • 119,623
  • 25
  • 170
  • 301
mumu
  • 11
  • 3
  • Please update your question with the full error traceback. – quamrana Aug 22 '20 at 19:50
  • 1
    Use `command=self.okClick` in the `__init__()` method when creating the `Button` to specify the callback function. – martineau Aug 22 '20 at 19:52
  • Error traceback is like below ;) Thanks! Exception has occurred: NameError name 'okClick' is not defined File "D:\Codes\2048\Memo.py", line 45, in __init__ button1=Button(frame4,text='csv Export',command=okClick) File "D:\Codes\2048\Memo.py", line 50, in a=memo(b) – mumu Aug 22 '20 at 19:55
  • Thank you. Now update the question with these details. – quamrana Aug 22 '20 at 19:59
  • @SangMuMu Your latest error might be because of indentation error? you should indent, `def__init__(..)` inside of the `class memo(..)` block – Delrius Euphoria Aug 22 '20 at 20:01
  • @martineau I updated as you adviced and now it says like "AttributeError: 'memo' object has no attribute 'entry1'" can you advice me once more? – mumu Aug 22 '20 at 20:09
  • Again, all ‘entry1’ should be ‘self.entry1’ – quamrana Aug 22 '20 at 20:10
  • @CoolCloud I edited my code. I didn't know how to copy and paste my code in this stackoverflow form thus I had to insert 4 spaces manually every code line. ;) – mumu Aug 22 '20 at 20:13
  • @SangMuMu The edit seems ok, and what is the problem now? – Delrius Euphoria Aug 22 '20 at 20:15
  • 1
    You can add code by first copying and pasting it, then select what you just pasted and click on the the question's edit box `{}` button (or type Ctrl-k). – martineau Aug 22 '20 at 20:16
  • @quamrana It works thanks very much! I cannot understand when I have to write self. in front of the classes or functions that I want to define. In this code there are cases that do function without self in front of it. – mumu Aug 22 '20 at 20:20
  • Sang MuMu: Sorry, I'm not sure what caused that `AttributeError`, as I get a different one when I try to run the latest code in your question. – martineau Aug 22 '20 at 20:21
  • @CoolCloud Thanks to you a lot of time would be saved :) – mumu Aug 22 '20 at 20:23
  • It sounds like it’s time to ask a new question. – quamrana Aug 22 '20 at 20:24
  • In your `okClick()` method there's a reference to `self.entry1` but your `__init__()` method doesn't create an instance attribute by that name. – martineau Aug 22 '20 at 20:37
  • This question should be closed as a typo or at least a dupe if only I could find one. – quamrana Aug 22 '20 at 20:39
  • Does this answer your question? ["NameError\[Command Name\] is not defined" When Using Buttons in Tkinter](https://stackoverflow.com/questions/56050683/nameerrorcommand-name-is-not-defined-when-using-buttons-in-tkinter) – quamrana Aug 22 '20 at 21:15

1 Answers1

3

You have a few things wrong with your code:

  1. onClick needs the "self" param passed to it and you need to update "command=onClick" to "command=self.onClick"

  2. Your entry1 variable should be set to an instance variable by prepending it with "self" so that it is accessible from the onClick method. Variable scope is a little different in python OOP.

from tkinter import *
from tkinter import messagebox
from tkinter import ttk
from tkcalendar import DateEntry

class Memo(Frame):
    def __init__(self,master):
        Frame.__init__(self,master)
        self.master=master
        self.master.title('Memo')
        self.pack(fill=BOTH, expand=True)

        frame1=Frame(self,width=500,height=50)
        frame1.pack(expand=False)
        label1=Label(frame1,text='Amount',width=10)
        label1.pack(side=LEFT, padx=10,pady=10)
        self.entry1=Entry(frame1,width=20)
        self.entry1.pack(padx=10,fill=X,expand=True)

        frame2=Frame(self,width=500,height=50)
        frame2.pack(expand=False)
        label2=Label(frame2,text='Cartegory',width=10)
        label2.pack(side=LEFT, padx=10,pady=10)
        listbox1=Listbox(frame2,width=20)
        listbox1.insert(END,"식료품비","잡화비","건강관리비","외식비")
        listbox1.pack(side=LEFT, padx=10,pady=10)

        frame3=Frame(self,width=500,height=50)
        frame3.pack(expand=False)
        label3=Label(frame3,text='Date',width=10)
        label3.pack(side=LEFT, padx=10,pady=10)
        dateentry = DateEntry(frame3)
        dateentry.pack(padx=10,pady=10)

        frame4=Frame(self,width=500,height=500)
        frame4.pack(expand=False)
        button1=Button(frame4,text='csv Export',command=self.okClick)
        button1.pack(side=LEFT,padx=10,pady=10)

    def okClick(self):
        name = self.entry1.get()
        messagebox.showinfo("이름", name)

if __name__ == "__main__":
    a=Memo(Tk())
    a.mainloop()
3dnerd
  • 66
  • 3
  • Thank you so much for your help :) Not easy to discern yet as a beginner when to use self. or not. – mumu Aug 24 '20 at 11:39