I have a little problem with my code. I have to make a sumator but I have an error and I don't know where I have a mistake. It says
"AttributeError: 'Application' object has no attribute 'create_widgets'.
I would be grateful if you help me fix the problem!
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master = None):
super().__init__(master)
self.pack()
self.create_widgets()
#create the app
app = Application()
app.master.frame()
app.master.title("Sumator")
app.master.minsize(width=100, height=50)
#start the program
app.mainloop()
def create_widgets(self):
#create widgets
self.firstNumberEntry = tk.Entry()
self.plusSign = tk.Label(text = "+")
self.secondNumberEntry = tk.Entry()
self.equalSign = tk.Label(text = "=")
self.resultLabel = tk.Label(text = "Result...", bg = "green", fg = "white")
self.calculateButton = tk.Button(text = "Calculate", command = self.calculate)
#place widgets
self.firstNumberEntry.pack(side = "left")
self.plusSign.pack(side = "left")
self.secondNumberEntry.pack(side = "left")
self.equalSign.pack(side = "left")
self.resultLabel.pack(side = "left")
self.calculateButton.pack(side = "left")
def calculate(self):
try:
first_value = float(self.firstNumberEntry.get())
second_value = float(self.secondNumberEntry.get())
result = first_value + second_value
self.resultLabel.config(text = str(result), bg = "green", fg = "white")
except ValueError:
self.resultLabel.config(text="No number/s", bg="red", fg="black")```
Your methods create_widgets and calculate are not in your class actually, they should be indented like the __init__ , like this
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master = None):
super().__init__(master)
self.pack()
self.create_widgets()
def create_widgets(self):
#...
def calculate(self):
#...
#create the app
app = Application()
app.master.frame()
app.master.title("Sumator")
app.master.minsize(width=100, height=50)
#start the program
app.mainloop()
You need to indent the calculate(self) function and the create_widgets(self) function into your Application class. This way, python knows they are part of the class.
I also made several improvements to your program, such as making it look nicer.
Here is the final code:
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master = None):
super().__init__(master)
self.pack()
self.create_widgets()
def create_widgets(self):
#create widgets
self.firstNumberEntry = tk.Entry(bd = 0)
self.plusSign = tk.Label(text = "+")
self.secondNumberEntry = tk.Entry(bd = 0)
self.equalSign = tk.Label(text = "=")
self.resultLabel = tk.Label(text = "Result...", bg = "green", fg = "white")
self.calculateButton = tk.Button(text = "Calculate", command = self.calculate, bd = 0, relief = "flat")
self.calculateButton.config(activebackground = self.calculateButton.master.cget("bg"))
#place widgets
self.firstNumberEntry.pack(side = "left")
self.plusSign.pack(side = "left")
self.secondNumberEntry.pack(side = "left")
self.equalSign.pack(side = "left")
self.resultLabel.pack(side = "left")
self.calculateButton.pack(side = "left")
def calculate(self):
try:
first_value = float(self.firstNumberEntry.get())
second_value = float(self.secondNumberEntry.get())
result = first_value + second_value
self.resultLabel.config(text = str(result), bg = "green", fg = "white")
except ValueError:
self.resultLabel.config(text="No number/s", bg="red", fg="black")
#create the app
app = Application()
app.master.frame()
app.master.title("Sumator")
app.master.minsize(width=100, height=50)
#start the program
app.mainloop()
Hope this helps you!
Related
Here's my code of a gui app using tkinter library, it creats tables and prints orders for each table and gives the ability to edit orders on every table. the goal of it to know what did each table order. but editing the orders doesn't seem to work at all, I need help fixing it.
import tkinter as tk
class TableOrdersApp:
def __init__(self, master):
self.tables = []
self.table_list = tk.Listbox(master)
self.table_list.pack(side=tk.LEFT, fill=tk.BOTH)
self.table_list.bind("<<ListboxSelect>>", self.refresh_label)
self.orders_label = tk.Label(master, text="", anchor=tk.W, justify=tk.LEFT, wraplength=400)
self.orders_label.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
self.button_frame = tk.Frame(master)
self.button_frame.pack(side=tk.RIGHT)
self.add_button = tk.Button(self.button_frame, text="Add Table", command=self.add_table)
self.add_button.pack(side=tk.TOP)
self.remove_button = tk.Button(self.button_frame, text="Remove Table", command=self.remove_table)
self.remove_button.pack(side=tk.TOP)
self.edit_button = tk.Button(self.button_frame, text="Edit Order", command=self.edit_order)
self.edit_button.pack(side=tk.TOP)
self.remove_order_button = tk.Button(self.button_frame, text="Remove Order", command=self.remove_order)
self.remove_order_button.pack(side=tk.TOP)
def add_table(self):
self.tables.append([])
self.table_list.insert(tk.END, "Table {}".format(len(self.tables)))
def remove_table(self):
index = self.table_list.curselection()[0]
self.tables.pop(index)
self.table_list.delete(index)
def refresh_label(self, event=None):
self.orders_label.config(text="\n".join(self.tables[self.table_list.curselection()[0]]))
def edit_order(self):
index = self.table_list.curselection()[0]
orders = self.tables[index]
if self.orders_label.select_present():
start_index = self.orders_label.index(tk.SEL_FIRST)
end_index = self.orders_label.index(tk.SEL_LAST)
selected_text = self.orders_label.selection_get()
num_newlines = selected_text.count("\n")
order_index = start_index.split(".")[0] - 1 - num_newlines
new_order = tk.simpledialog.askstring("Edit Order", "Enter the new order:")
orders[order_index] = new_order
self.refresh_label()
def remove_order(self):
index = self.table_list.curselection()[0]
orders = self.tables[index]
start_index = self.orders_label.index(tk.SEL_FIRST)
end_index = self.orders_label.index(tk.SEL_LAST)
num_newlines = self.orders_label.get(start_index, end_index).count("\n")
order_index = start_index.split(".")[0] - 1 - num_newlines
orders.pop(order_index)
self.refresh_label()
# Create the main window
root = tk.Tk()
# Create an instance of the TableOrdersApp class
app = TableOrdersApp(root)
# Run the main loop of the app
root.mainloop()
I tried to make it print a label and make it editable using "edit order" button, but the button itself doesn't seem to work, and I want it to print "Empty" if the table has no orders how can i do that.
Look in edit_order and remove_order function. Must easier to write less coding.
Here is code:
import tkinter as tk
class TableOrdersApp:
def __init__(self, master):
self.tables = []
self.table_list = tk.Listbox(master)
self.table_list.pack(side=tk.LEFT, fill=tk.BOTH)
self.table_list.bind("<<ListboxSelect>>", self.refresh_label)
self.orders_label = tk.Label(master, text="", anchor=tk.W, justify=tk.LEFT, wraplength=400)
self.orders_label.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
self.button_frame = tk.Frame(master)
self.button_frame.pack(side=tk.RIGHT)
self.add_button = tk.Button(self.button_frame, text="Add Table", command=self.add_table)
self.add_button.pack(side=tk.TOP)
self.remove_button = tk.Button(self.button_frame, text="Remove Table", command=self.remove_table)
self.remove_button.pack(side=tk.TOP)
self.edit_button = tk.Button(self.button_frame, text="Edit Order", command=self.edit_order)
self.edit_button.pack(side=tk.TOP)
self.remove_order_button = tk.Button(self.button_frame, text="Remove Order", command=self.remove_order)
self.remove_order_button.pack(side=tk.TOP)
def add_table(self):
self.tables.append([])
self.table_list.insert(tk.END, "Table {}".format(len(self.tables)))
def remove_table(self):
index = self.table_list.curselection()[0]
self.tables.pop(index)
self.table_list.delete(index)
def refresh_label(self, event=None):
self.orders_label.config(text="\n".join(self.tables[self.table_list.curselection()[0]]))
def edit_order(self):
index = self.table_list.curselection()[0]
orders = self.table_list.get(index)
print(index)
order = orders
self.orders_label.configure(text=order)
#if self.orders_label.select_present():
#start_index = self.orders_label.index(tk.SEL_FIRST)
#end_index = self.orders_label.index(tk.SEL_LAST)
#selected_text = self.orders_label.selection_get()
#num_newlines = selected_text.count("\n")
#order_index = start_index.split(".")[0] - 1 - num_newlines
#new_order = tk.simpledialog.askstring("Edit Order", "Enter the new order:")
#orders[order_index] = new_order
#self.refresh_label()
def remove_order(self):
remove_orders = self.table_list.curselection()
self.table_list.delete(remove_orders)
self.orders_label.configure(text="")
#index = self.table_list.curselection()[0]
#orders = self.tables[index]
#start_index = self.orders_label.index(tk.SEL_FIRST)
#end_index = self.orders_label.index(tk.SEL_LAST)
#num_newlines = self.orders_label.get(start_index, end_index).count("\n")
#order_index = start_index.split(".")[0] - 1 - num_newlines
#orders.pop(order_index)
#self.refresh_label()
# Create the main window
root = tk.Tk()
# Create an instance of the TableOrdersApp class
app = TableOrdersApp(root)
# Run the main loop of the app
root.mainloop()
Result when executes:
Result when selected:
Result when removed order:
I need help inserting text in a Text widget that's part of a Frame.
class Test_frame(Frame):
def __init__(self):
Frame.__init__(self)
self.config(width = 700, height = 450)
self.logs_frame = LabelFrame(self, height = 402, width = 348, text = 'Logs')
self.logs_frame.grid(column = 1, row = 0, pady=10, sticky = N)
self.logs_frame.grid_propagate(0)
self.text_box = Text(self.logs_frame, width=40, pady=10, height=22)
self.text_box.pack(side="left")
self.scroll_y = Scrollbar(self.logs_frame, orient="vertical", command=self.text_box.yview)
self.scroll_y.pack(side="left", expand=True, fill="y")
self.text_box.configure(yscrollcommand=self.scroll_y.set)
self.text_box.insert (?????.END, "Sample Text")
I have no idea how to access that Text widget now.
Test_frame is part of a Notebook:
class App(Tk):
def __init__(self):
Tk.__init__(self)
self.my_notebook = ttk.Notebook(self)
self.my_notebook.pack(pady = 5)
self.frames = {}
for F in (Test_frame, Final_flash_frame):
frame = F()
self.frames[F] = frame
frame.pack(fill = 'both', expand = 1)
self.my_notebook.add(self.frames[Test_frame], text = "Testing")
I created a minimal source, but I guess you solved your problem.
I added a little button to add text, and added some text from outside the class.
Here it is, anyway:
import tkinter as Tk
import tkinter.ttk as ttk
from tkinter import *
def BumpText(textbox):
textbox.insert(END,", MORE TEXT")
class Test_frame(Frame):
def __init__(self):
Frame.__init__(self)
self.config(width = 700, height = 450)
self.logs_frame = LabelFrame(self, height = 402, width = 348, text = 'Logs')
self.logs_frame.grid(column = 1, row = 0, pady=10, sticky = N)
self.logs_frame.grid_propagate(0)
self.text_box = Text(self.logs_frame, width=40, pady=10, height=22)
self.text_box.pack(side="left")
self.scroll_y = Scrollbar(self.logs_frame, orient="vertical", command=self.text_box.yview)
self.scroll_y.pack(side="left", expand=True, fill="y")
self.text_box.configure(yscrollcommand=self.scroll_y.set)
self.text_box.insert(END, "Sample Text")
self.button = Button(self.logs_frame, text="Add\nText", command=lambda:self.text_box.insert(END, ", More Text"))
self.button.pack(side="bottom")
class App(Tk):
def __init__(self):
Tk.__init__(self)
self.my_notebook = ttk.Notebook(self)
self.my_notebook.pack(pady = 5)
self.frames = {}
for F in (Test_frame,): # , Final_flash_frame):
frame = F()
self.frames[F] = frame
frame.pack(fill = 'both', expand = 1)
self.my_notebook.add(self.frames[Test_frame], text = "Testing")
for F,f in self.frames.items():
try:
f.text_box.insert(END," (Added by App)")
except Exception as e:
pass # ignore frames without text_box
if __name__ == "__main__":
App().mainloop()
Ok, so apparently just using:
self.text_box.insert (END, "Sample Text")
works
Cheers,
A
I am trying to make a GUI for my program but I have changed my code a lot and I saw that GUI misses one frame but it was fine before.
Could anyone help me and tell why a frame with a button does not appear on the bottom?
Whole "button_part" object does not appear.
from tkinter import *
import tkinter as tk
import os
import glob
BOUNDS = ["Last week", "Last 2 weeks", "Last 3 weeks"]
class settings_part:
path_to_copy = 0
def __init__(self, master, update_func):
path_to_copy = StringVar()
settings_frame = Frame(master, background="")
settings_frame.pack(side=TOP, fill=X)
date_bound = StringVar()
date_bound.set(BOUNDS[1])
date_option = OptionMenu(settings_frame, date_bound, *BOUNDS, command=update_func)
date_option.config(background="#732c30")
date_option.config(foreground="white")
date_option.config(bd=0)
date_option.pack(side=LEFT, padx=5, pady=5)
path_to_copy.set("~/Python/usun")
box_with_path = Entry(settings_frame, textvariable=path_to_copy)
box_with_path.pack(side=RIGHT, padx=5, pady=5)
# s = path_to_copy.get()
class songs_part:
def __init__(self, master, root):
self.songs_frame = Frame(master)
self.update_songs(root.list_of_songs)
self.songs_frame.pack()
def update_songs(self, l):
for song in l:
c = Checkbutton(self.songs_frame, text=song[0], variable=song[1])
c.pack()
class button_part:
def __init__(self, master, copyFunc):
self.button_frame = Frame(master)
btn_image = PhotoImage(file="copybtn.png")
self.copy_button = Button(self.button_frame, command=copyFunc, text="Copy",
image=btn_image, highlightthickness=0, bd=0, activebackground="#732c30")
self.copy_button.pack()
class App:
def __init__(self):
root = Tk()
root.title("Copying songs")
root.geometry("500x500")
root.option_add("*Font", "Calibra")
back_image = PhotoImage(file="back.png")
self.window = Label(root, image=back_image)
self.window.pack(fill="both", expand="yes")
self.list_of_songs = list()
self.make_list_of_songs()
self.set_part = settings_part(self.window, self.update_list)
self.son_part = songs_part(self.window, self)
self.but_part = button_part(self.window, self.copy_songs)
root.mainloop()
def make_list_of_songs(self):
owd = os.getcwd()
os.chdir("/home/stanek/Music/usun")
for file in glob.glob("*.mp3"):
self.list_of_songs.append([file, tk.IntVar()])
os.chdir(owd)
def copy_songs(self):
for s in self.list_of_songs:
print(s)
def update_list(self, arg):
print("updating list with songs from " + arg)
self.son_part = songs_part(self.window, self)
if __name__ == '__main__':
App()
You never pack the button frame.
i have a small ui programm and i need to display a calendar in it or a date picker . (NOTE : userid and password is root")**
i have tried this code :
from Tkinter import *
from PIL import Image, ImageTk
import ttkcalendar
class App():
def __init__(self):
pass
root = Tk()
root.configure(bg='black')
root.attributes('-alpha', 0.0)
def mainWindow(self):
self.root.geometry('{}x{}'.format(600,400))
self.root.attributes('-alpha', 1)
self.root.configure(bg='#404040')
self.ttkcal = ttkcalendar.Calendar(self.root,firstweekday=calendar.SUNDAY)
self.ttkcal.pack()
self.root.wm_title("time sheet management system")
# Create the toolbar as a frame
self.toolbar = Frame(self.root, borderwidth=1, relief='raised')
self.toolbar.configure( bg = '#838383')
# Load all the images first as PNGs and use ImageTk to convert
# them to usable Tkinter images.
self.img1 = Image.open('NewIcon.png')
self.useImg1 = ImageTk.PhotoImage(self.img1)
self.img2 = Image.open('LoadIcon.png')
self.useImg2 = ImageTk.PhotoImage(self.img2)
self.img3 = Image.open('SaveIcon.png')
self.useImg3 = ImageTk.PhotoImage(self.img3)
# Set up all the buttons for use on the toolbars.
newBtn = Button(self.toolbar, image=self.useImg1, command=self.callback)
newBtn.pack(side=LEFT, fill=X)
loadBtn = Button(self.toolbar, image=self.useImg2, command=self.callback)
loadBtn.pack(side=LEFT, fill=X)
saveBtn = Button(self.toolbar, image=self.useImg3, command=self.callback)
saveBtn.pack(side=LEFT, fill=X)
# Add the toolbar
self.toolbar.pack(side=TOP, fill=X)
"""
#create a frame
self.infoArea= Frame(self.root, borderwidth=2,height=40,width=100, relief='raised',bg='red')"""
self.root.mainloop()
"""
# Set up a Text box and scroll bar.
self.scrollbar = Scrollbar(self.root)
self.scrollbar.pack(side=RIGHT, fill=Y)
self.text = Text(self.root)
self.text.pack()
self.text.config(yscrollcommand=self.scrollbar.set)
self.scrollbar.config(command=self.text.yview)"""
def loginClick(self):
self.userid = self.txt1.get()
self.password = self.txt2.get()
print self.userid,self.password
if self.password == 'root' and self.userid == 'root':
self.wi.destroy()
self.mainWindow()
def callback(self):
print "A button was pressed"
def login(self):
self.wi = Toplevel (self.root)
#self.wi.geometry('{}x{}'.format(200,200))
self.wi.configure(bg='#404040')
self.wi.overrideredirect(1)
self.wi.update_idletasks()
self.w = self.wi.winfo_screenwidth()
self.h = self.wi.winfo_screenheight()
self.size = tuple(int(_) for _ in self.wi.geometry().split('+')[0].split('x'))
self.x = self.w/2 - self.size[0]/2
self.y = self.h/2 - self.size[1]/2
self.wi.geometry("%dx%d+%d+%d" % (self.size + (self.x, self.y)))
self.wi.geometry('{}x{}'.format(400,200))
self.frame1 = Frame ( self.wi,bg='#404040' )
self.frame1.pack(side=BOTTOM,fill=X)
self.butt1 = Button(self.frame1,text= "Cancel" , bg = '#838383',fg='white',command = self.wi.destroy)
self.butt1.pack(side=RIGHT,padx=1)
self.butt2 = Button(self.frame1,text= "Login" ,bg = '#838383',fg='white',command = self.loginClick)
self.butt2.pack(side=RIGHT)
"""self.frame2 = Frame ( self.wi,bg='green' )
self.frame2.pack(side=BOTTOM,fill=BOTH)"""
self.lab1 = Label (self.wi,text='UserID',bg='#404040',fg='white')
#self.lab1.pack(side=LEFT,padx=60,pady=20)
self.lab1.place(x=60,y=20)
self.lab2 = Label (self.wi,text='Password',bg='#404040',fg='white')
#self.lab1.pack(side=LEFT,padx=60,pady=20)
self.lab2.place(x=60,y=60)
self.txt1 = Entry( self.wi)
self.txt1.place(x=140,y=20)
self.txt2 = Entry( self.wi,show='*')
self.txt2.place(x=140,y=60)
"""
self.label = Label(self.wi,text="UserID",bg='#838383',fg='white')
self.label.place("""
self.wi.mainloop()
if __name__ == "__main__":
a = App()
#a.root.mainloop()
a.login()
but it is giving error that "name calendar not defined". how can i solve this ?
or is there any other way to implement a calendar or date picker in tkinter.
The code is using calendar module, but it is not importing the module.
self.ttkcal = ttkcalendar.Calendar(self.root, firstweekday=calendar.SUNDAY)
^^^^^^^^^^^^^^^
Simply adding following import statement will solve the problem.
import calendar
I am a beginner programmer and want to open a new window after a bottom in clicked in tkinter. I looked online and tried some things but I don't really understand it and keep getting errors. Here is the error I get now.
File "C:\Python33\lib\tkinter\__init__.py", line 2046, in _setup
self.tk = master.tk
AttributeError: 'App' object has no attribute 'tk'
Here is my code
from tkinter import *
import random
player_dice = []
class App:
def __init__(self, master):
for i in range(1,6):
x = random.randint(1,6)
player_dice.append(x)
self.label = Label(master, text = x , fg = "red").grid(row =0, column =i+1)
self.label = Label(master, text = "Dice:" , fg = "red").grid(row =0, column =1)
self.hi_one = Button(master, text="one", command=self.say_one).grid(row = 1, column = 1)
def say_one(self):
print ("1")
window = Toplevel(self)
self.label = Label(window, text = "you selected one" , fg = "red").grid(row =3, column =3)
root = Tk()
app = App(root)
root.mainloop()
thanks for your help
Pass root, not self when call Toplevel: Toplevel(root). Or omit argument: Toplevel()
from tkinter import *
import random
player_dice = []
class App:
def __init__(self, master):
for i in range(1,6):
x = random.randint(1,6)
player_dice.append(x)
self.label = Label(master, text = x , fg = "red").grid(row =0, column =i+1)
self.label = Label(master, text = "Dice:" , fg = "red").grid(row =0, column =1)
self.hi_one = Button(master, text="one", command=self.say_one).grid(row = 1, column = 1)
def say_one(self):
print ("1")
window = Toplevel(root) # self -> root
self.label = Label(window, text = "you selected one" , fg = "red").grid(row =3, column =3)
root = Tk()
app = App(root)
root.mainloop()