AttributeError or ImportError in python calculator program - python

I am writing a calculator program with python, and i keep getting an error message
AttributeError: 'Application' object has no attribute 'response_txt'
from tkinter import *
class Application(Frame):
""" GUI application calculator. """
def __init__(self, master):
""" Initialize the frame. """
super(Application, self).__init__(master)
# Adds the grid layout manager
self.grid()
# The result string
self.response_str = ""
#sets up the controls in the frame
self.create_widgets()
def create_widgets(self):
""" Create and sequence """
#Text Sequence
self.sequence_txt = Text(self, height = 1, width = 30, wrap=WORD)
self.sequence_txt.grid(row = 0, column = 0, columnspan = 2)
# Configure the Text to center
self.sequence_txt.tag_config("center_align", justify='center')
# Configure the Text to center
self.response_txt.tag_config("center_align", justify='center')
###buttons
# Button 1
Button(self,
bg='1',
command = self.one_btn_clicked,
height = 2
).grid(row = 2, column = 0, sticky = NSEW)
#buttons clicked
def one_btn_clicked(self):
"""This method is run when the one button gets clicked"""
#append a 1
self.response_str+="1"
#update text
self.response_txt.delete(0.0, END)
self.response_txt.insert(0.0, self.response_str, "center_align")
#add number
self.compare_sequences();
#main
root = Tk()
root.title("Calculator")
app = Application(root)
root.mainloop()
When i ran this through the module, it gave me this error:
AttributeError: 'Application' object has no attribute 'response_txt'
I tried importing a submodule like this:
`import self.response_txt`
And then it gave me this error message:
ImportError: No module named 'self'
I really need this to work, school assignment due tomorrow. Any ideas are appreciated, I am very new to programming. I am also aware that the program is not really that close to done, but before I can move to any other steps I need to make sure what I did here will work in the first place. Thank you.

You forgot to intitalise self.response_txt. Furthermore, '1' is not a valid argument for bg in the code:
Button(self,
bg='1',
command = self.one_btn_clicked,
height = 2
).grid(row = 2, column = 0, sticky = NSEW)
Corrected code:
from tkinter import *
class Application(Frame):
""" GUI application calculator. """
def __init__(self, master):
""" Initialize the frame. """
super(Application, self).__init__(master)
# Adds the grid layout manager
self.grid()
# The result string
self.response_str = ""
#sets up the controls in the frame
self.create_widgets()
def create_widgets(self):
""" Create and sequence """
#Text Sequence
self.sequence_txt = Text(self, height = 1, width = 30, wrap=WORD)
self.sequence_txt.grid(row = 0, column = 0, columnspan = 2)
self.response_txt = Text(self, height = 1, width = 30, wrap=WORD)
self.response_txt.grid(row = 0, column = 0, columnspan = 2)
# Configure the Text to center
self.sequence_txt.tag_config("center_align", justify='center')
# Configure the Text to center
self.response_txt.tag_config("center_align", justify='center')
###buttons
# Button 1
Button(self,
bg='white',
command = self.one_btn_clicked,
height = 2
).grid(row = 2, column = 0, sticky = NSEW)
#buttons clicked
def one_btn_clicked(self):
"""This method is run when the one button gets clicked"""
#append a 1
self.response_str+="1"
#update text
self.response_txt.delete(0.0, END)
self.response_txt.insert(0.0, self.response_str, "center_align")
#add number
self.compare_sequences();
#main
root = Tk()
root.title("Calculator")
app = Application(root)
root.mainloop()
Also you haven't created compare_sequences function.

Related

Working with GUIs and text files - how do I 'synchronize' them?

I am working on a larger programming project, and since I am a beginner it is not that complex. I will try to keep it straight forward: I want to create a GUI program that reads from a text file with "elements of notes", i.e. as a calendar.
The interface should have "text entry box", where you can submit new notes, and there should also be two buttons that upon pressing them "scrolls" up and down among the existing notes, i.d. turning page. A single note should be displayed at all times in a text box under the two buttons.
So, to wrap this up, my question is: How is the best way to "load" the text file's notes to the program, so that I can make the buttons scroll between them? Should I read the text file into a list that I give my Application(Frame) object?
Here is some of my code so far:
from tkinter import *
class Application(Frame):
""" GUI application that creates diary. """
def __init__(self, master):
""" Initialize Frame. """
Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
""" Create widgets to get info of choices and display notes. """
# create a label and text entry for new note
Label(self,
text = "Enter new note:"
).grid(row = 1, column = 0, sticky = W)
self.note_ent = Entry(self)
self.note_ent.grid(row = 1, column = 1, sticky = W)
# create a submit button for the new note
Button(self,
text = "Submit",
# command = self.add_note to a list within app obeject?
).grid(row = 2 column = 0, sticky = W)
# create a 'next note' button
Button(self,
text = "Next",
# command = self.next_note which goes to a list?
).grid(row = 6, column = 0, sticky = W)
# create a 'past note' button
Button(self,
text = "Back",
# command = self_past_note, or should I reuse next_note?
).grid(row = 6, column = 0, sticky = W)
# create a textbox (I am not sure?)
self.show_ent = Text(self, width = 75, height = 10, wrap = WORD)
self.show_ent.grid(row = 7, column = 0, columnspan = 4)
# main
text_file = open("diary.txt", "r")
note_list = text_file.readlines()
text_file.close()
# No idea where to put the note_list, which 'client' should receive it?
root = Tk()
root.title("Diary")
app = Application(root)
root.mainloop()
So now that you have examined my code, how to fill in the missing pieces?
Edit: I added the text_file and note_list under the # main.
Note: I have used calendar and diary interchangeably, but the program is more of a calendar.
You can use it inside Application class:
from Tkinter import *
class Application(Frame):
""" GUI application that creates diary. """
def __init__(self):
""" Initialize Frame. """
Frame.__init__(self)
self.note_list = []
with open("diary.txt", "r") as notes:
self.note_list = text_file.readlines()
self.grid()
self.create_widgets()
def create_widgets(self):
""" Create widgets to get info of choices and display notes. """
# create a label and text entry for new note
Label(self,
text = "Enter new note:"
).grid(row = 1, column = 0, sticky = W)
self.note_ent = Entry(self)
self.note_ent.grid(row = 1, column = 1, sticky = W)
# create a submit button for the new note
Button(self,
text = "Submit",
# command = self.add_note to a list within app obeject?
).grid(row = 2, column = 0, sticky = W)
# create a 'next note' button
Button(self,
text = "Next",
# command = self.next_note which goes to a list?
).grid(row = 6, column = 0, sticky = W)
# create a 'past note' button
Button(self,
text = "Back",
# command = self_past_note, or should I reuse next_note?
).grid(row = 6, column = 0, sticky = W)
# create a textbox (I am not sure?)
self.show_ent = Text(self, width = 75, height = 10, wrap = WORD)
self.show_ent.grid(row = 7, column = 0, columnspan = 4)
app = Application()
app.master.title("Diary")
app.mainloop()

Tkinter in Python - Entry widget not displaying

I am trying to make an entry widget display beneath a Label using the .grid() function; however, it is simply not showing up. Here is my code:
#demonstrates how to use a class with Tkinter
from Tkinter import *
import tkMessageBox
class Application(Frame):
def __init__(self, master):
""" Initializes the Frame"""
Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
self.previous_trans = Text(width = 100, height = 5, wrap = WORD)
self.previous_trans.grid(row = 0, column = 0, columnspan = 2)
self.items = Text(width = 50, height = 16, wrap = WORD)
self.items.grid(row = 1, column = 1, rowspan = 14, sticky = E)
self.additem = Label(text = "Add Item")
self.additem.grid(row = 1)
self.myentry = Entry(self)
self.myentry.grid(row = 2)
root = Tk();
root.title("Work In Progress")
app = Application(root)
root.mainloop();
The reason is because:
you don't specify a row or column for app, so it defaults to 0,0
you don't specify a parent for self.previous_trans so it defaults to the root window -- the same as for the application frame
you explicitly put self.previous_trans in row zero, column zero, which overwrites the label
You need to be giving an explicit parent of self to all of the widgets inside of Application:
self.previous_trans = Text(self, ...)
self.items = Text(self, ...)
self.additem = Label(self, ...)
self.myentry = Entry(self, ...)

Duplicate Frames Created When Calling a Function in a Tkinter Application

So this is my first Python GUI project utilizing tkinter. I come from a background in R.
I decided after a review of the documentation to create a class to handle the bulk of the work. The problem appears with my incrementer functions fwd() and bck(). If I do not call these functions in the following chunk of code:
class App:
def __init__(self, master):
....
self.total = 2
self.fwd()
self.bck()
The output of the entire code is an empty tkinter frame.
On the other hand, if I do call them, the fwd() function works as one would expect, but every time I click the back button (command = bck()), a new and identical GUI will be attached directly to the bottom of my current GUI. If I click the back button again, another GUI will pop up behind the current GUI.
from tkinter import *
from tkinter import font
from tkinter import filedialog
class App: #I'm not typing what goes in this class, this way I can avoid issues with App(Frame), etc. DUCKTYPE!
def __init__(self, master):
self.frame = Frame(master)
self.frame.pack()
self.master = master
master.title("PyCCI Caste")
self.total = 2
self.fwd() #Need to call these at the beginning otherwise the window is minimized??? No idea why.
self.bck() #The back button creates a duplicate window...
## +Incrementer
def fwd(self):
self.total += 1
print(self.total)
## -Incrementer THIS CREATES A SECOND PANED WINDOW, WHY?!
def bck(self):
self.total += -1
if self.total < 3:
self.total = 2
print(self.total)
#Body
self.k1 = PanedWindow(self.frame, #Note: if this is not self.frame, the error: 'App' object has no attribute 'tk' is thrown
height=500,
width=750,
orient = VERTICAL)
self.k1.pack(fill=BOTH, expand = 1)
self.titlefont = font.Font(size = 12,
weight = 'bold')
self.boldfont = font.Font(size=8,
weight = 'bold')
self.textfont = font.Font(family = 'Arial',
size = 10)
#Title
self.title = PanedWindow(self.k1)
self.k1.add(self.title, padx = 10, pady = 10)
Label(self.title, text = "Chronic Critically Ill Patient GUI",
font = self.titlefont,
fg="darkslateblue").pack()
#Top row open csv window & button
self.k2 = PanedWindow(self.k1)
self.k1.add(self.k2)
self.openbutton = Button(self.k2,
text = "Open CSV")#, command = openfile())
self.openbutton.pack(side = LEFT,
padx = 30)
#Panes below buttons
self.k3 = PanedWindow(self.k1)
self.k1.add(self.k3)
self.leftpane = PanedWindow(self.k3)
self.k3.add(self.leftpane,
width = 400,
padx = 30,
pady = 25,
stretch = "first")
self.separator = PanedWindow(self.k3,
relief = SUNKEN)
self.k3.add(self.separator,
width=2,
padx=1,
pady=20)
self.rightpane = PanedWindow(self.k3)
self.k3.add(self.rightpane,
width = 220,
padx = 10,
pady = 25,
stretch = "never")
#Left pane patient note text frame doo-diddly
self.ptframe = LabelFrame(self.leftpane,
text = "Medical Record",
font = self.boldfont,
padx = 0,
pady=0,
borderwidth = 0)
self.ptframe.pack()
Label(self.ptframe,
text = "patient # of ##").pack()
#Incrementer buttons
self.buttonframe = Frame(self.ptframe)
self.buttonframe.pack()
self.buttonframe.place(relx=0.97, anchor = NE)
#Back Button
self.button1 = Button(self.buttonframe, text = 'Back', width = 6, command = self.bck)
self.button1.grid(row = 0, column = 0, padx = 2, pady = 2)
#Next Button
self.button2 = Button(self.buttonframe, text = 'Next', width = 6, command = self.fwd)
self.button2.grid(row = 0, column = 2, padx = 2, pady = 2)
#Scrollbar!
self.ptscroll = Scrollbar(self.ptframe)
self.ptscroll.pack(side = RIGHT, fill = Y)
self.pttext = Text(self.ptframe,
height=300,
width=400,
wrap=WORD,
font=self.textfont,
spacing1=2,
spacing2=2,
spacing3=3,
padx=15,
pady=15)
self.pttext.pack()
self.ptscroll.config(command=self.pttext.yview)
self.pttext.config(yscrollcommand=self.ptscroll.set)
#Checkbuttons
self.checkframe = LabelFrame(self.rightpane, text="Indicators",
font=self.boldfont,
padx = 10,
pady = 10,
borderwidth=0)
self.checkframe.pack()
self.check1 = Checkbutton(self.checkframe, text="Non-Adherence")
self.check1.grid(row = 1,
column = 0,
sticky = W)
root = Tk()
app = App(root) ## apply the class "App" to Tk()
### Menu stuff does not need to be part of the class
menubar = Menu(root)
filemenu = Menu(menubar, tearoff=0)
filemenu.add_command(label="Open CSV")#, command=openfile)
menubar.add_cascade(label="File", menu=filemenu)
helpmenu = Menu(menubar, tearoff=0)
helpmenu.add_command(label="About")#, command=about)
menubar.add_cascade(label="Help", menu=helpmenu)
root.config(menu=menubar)
root.mainloop()
What do you folks think? If I'm missing any pertinent information here, please let me know. The difficulty I'm having is that I don't know what I don't know about Python/Tkinter yet.
Thanks, I really appreciate any insight and direction.
Solved (thanks Bryan Oakley & TigerhawkT3): Due to Python's use of indentation as part of its syntax, I had created a function bck() which, when called, includes the code for the entirety of the rest of the GUI. To solve this problem after it was pointed out, I drew heavily from:
Python def function: How do you specify the end of the function?
You appear you have a simple indentation error. It seems like you intend for bck to have four lines of code, but because almost all of the remaining code is indented the same, it is all considered to be part of bck.

Empty Tkinter Window

I am doing a bit of basic Tkinter code, and when I launch I get no errors, but my window is empty, even though I have added things to them. I saw this question here, but that does not help me, as I have what it says to do.
from tkinter import *
class App:
def __init__(self,master):
frame = Frame(master)
frame.pack
self.sg = Button(frame, text = "Study Guide", command = self.studyGuide)
self.sg.grid(row = 2, column = 1)
self.sg.pack()
self.quizlet = Button(frame, text = "Quizlet", command = self.quizlet)
self.quizlet.grid(row = 2, column = 2)
self.quizlet.pack()
self.flashcard = Button(frame, text = "Flash Cards", command = self.flashcard)
self.flashcard.grid(row = 2, column = 3)
self.flashcard.pack()
self.quitButton = Button(frame, text = "Quit", command = frame.quit)
self.quitButton.grid(row = 3, column = 2)
self.quitButton.pack()
self.text = Label(frame, text = "Social Studies Study Tool")
self.text.grid(row = 1, column = 2)
self.text.pack()
def studyGuide(self):
print("Study Guide")
def quizlet(self):
print("Quizlet")
def flashcard(self):
print("Flashcards")
root = Tk()
app = App(root)
root.mainloop()
First, for every element that you call grid for, don't call pack. You only need to use one or the other. Second:
frame = Frame(master)
frame.pack
You appear to be missing a parentheses here.
frame = Frame(master)
frame.pack()
Don't mix up layout managers! Use either pack() or grid(), but not both.
If you use pack, add the side where to pack the items:
frame.pack() # note the missing () in your code
...
self.sg.pack(side=TOP)
If you use grid(), add frame.grid() to the top of your code:
frame.grid()
...
self.sg.grid(row = 2, column = 1)

changing label automatically in python

I am trying to change a label automatically in python, I want it to change every half a second, this is my code for tkinter, the function being called (that is being put into "message") returns a new string every half a second, what am I doing wrong?
import Tkinter as tk
class Application(tk.Frame):
def __init__(self):
self.root = tk.Tk()
self.root.geometry("150x136")
tk.Frame.__init__(self, self.root)
self.create_widgets()
def create_widgets(self):
self.root.bind('<Return>', self.parse)
self.grid()
self.instruction = tk.Label(self, text = "QuickReader")
self.instruction.grid(row = 0, column = 0, columnspan = 4)
self.entry = tk.Entry(self)
self.entry.grid(row = 2, column = 0)
self.submit = tk.Button(self, text="Submit")
self.submit.bind('<Button-1>', self.parse)
self.submit.grid(row = 4, column = 0)
self.words = tk.Label(self, text = "Start")
self.words.grid(row = 5, column = 0, columnspan = 4)
def parse(self, event):
filename = self.entry.get()
message = open_txt(filename)
self.words.set(message)
def start(self):
self.root.mainloop()
Application().start()
To change label text, use one of following:
self.words.config(text=message)
self.words.configure(text=message)
self.words['text'] = message
http://effbot.org/tkinterbook/label.htm
You can associate a Tkinter variable with a label. When the contents of the variable changes, the label is automatically updated:
v = StringVar()
Label(master, textvariable=v).pack()
v.set("New Text!")
So, that should be pretty easy to implement.

Categories

Resources