delete(0, END) doesn't work for me - python

delete(0, END) does not work for some reason. It does not give any error messages and the rest of the code seems fine. The delete(0, END) won't delete the 0's I get in my entry boxes from the intvar and I cant figure out why it won't work. I'm using delete in another code and it works there. Could anyone help me out?
The code i got problem with.
part1_entry = tk.Entry(Frame1, font=('Helvetica', 12, 'bold'),
textvariable=self.a3, validate = 'key', validatecommand = vcmd, width = 11)
part1_entry.grid(column=0, row=6, sticky=(W), columnspan=1)
part1_entry.delete(0, END)
part2_entry = tk.Entry(Frame1, font=('Helvetica', 12, 'bold'),
textvariable=self.a5, validate = 'key', validatecommand = vcmd, width = 11)
part2_entry.grid(column=0, row=6, sticky=(E), columnspan=1)
part2_entry.delete(0, END)
Here is my code.
import tkinter as tk
from tkinter import ttk
import io
from tkinter import filedialog
E=tk.E
W=tk.W
N=tk.N
S=tk.S
VERTICAL=tk.VERTICAL
END=tk.END
class Demo1(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.master = master
self.Frame = tk.Frame(self.master, borderwidth=10)
self.Frame.grid(column=0, row=0, sticky=(N, W, E, S))
button1 = tk.Button(self.Frame, text="Special Rk märkning", command=self.new_window, width = 25)
button1.grid(column=0, row=0, sticky=(W, E), columnspan=4)
button2 = tk.Button(self.Frame, text="Billerud kabelmärkningar", command=self.new_window, width = 25)
button2.grid(column=0, row=1, sticky=(W, E), columnspan=4)
def new_window(self):
Billerud(self)
class Billerud:
def __init__(self, master):
self.master = master
top1 = tk.Toplevel()
top1.title("Billerud")
top1.resizable(width=False, height=False)
#fönster designern här bästems fönster ramar, rader och columner
Frame1 = tk.Frame(top1)
Frame1.grid(column=1, row=0, sticky=(N, W, E, S), padx=5, pady=5)
Frame1.columnconfigure(0, weight=1)
Frame1.rowconfigure(0, weight=1)
#Koden är en del av entry's endast nummer restriktion
vcmd = (Frame1.register(self.validate),
'%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
#create text editor
self.text_entry = tk.Text(Frame1, width=25,height=20)
self.text_entry.grid(column=0, row=0, sticky=(W, E))
scrollbar = tk.Scrollbar(Frame1, orient=VERTICAL)
scrollbar.grid(column=0, row=0, sticky=(N, E, S))
# koppla ihop listbox med scrollbar
self.text_entry.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=self.text_entry.yview)
self.a1 = tk.StringVar()
self.a2 = tk.StringVar()
self.a3 = tk.IntVar()
self.a4 = tk.StringVar()
self.a5 = tk.IntVar()
text1 = tk.Label(Frame1, text="Kabelnamn:", font=("Helvetica", 12, "bold")).grid(column=0, row=1, sticky=(W), columnspan=2)
Kabelnamn_entry = tk.Entry(Frame1, font=('Helvetica', 12, 'bold'), textvariable=self.a1)
Kabelnamn_entry.grid(column=0, row=2, sticky=(W, E), columnspan=2)
text2 = tk.Label(Frame1, text="Kabelnummer:", font=("Helvetica", 12, "bold")).grid(column=0, row=3, sticky=(W), columnspan=2)
Kabelnummer_entry = tk.Entry(Frame1, font=('Helvetica', 12, 'bold'), textvariable=self.a2)
Kabelnummer_entry.grid(column=0, row=4, sticky=(W, E), columnspan=2)
text3 = tk.Label(Frame1, text="Parter från: Till:", font=("Helvetica", 12, "bold")).grid(column=0, row=5, sticky=(W), columnspan=1)
part1_entry = tk.Entry(Frame1, font=('Helvetica', 12, 'bold'), textvariable=self.a3, validate = 'key', validatecommand = vcmd, width = 11)
part1_entry.grid(column=0, row=6, sticky=(W), columnspan=1)
part1_entry.delete(0, END)
part2_entry = tk.Entry(Frame1, font=('Helvetica', 12, 'bold'), textvariable=self.a5, validate = 'key', validatecommand = vcmd, width = 11)
part2_entry.grid(column=0, row=6, sticky=(E), columnspan=1)
part2_entry.delete(0, END)
button1 = tk.Button(Frame1, text="Make", command=self.funktion, width = 16)
button1.grid(column=0, row=7, sticky=(W, E), columnspan=4)
button2 = tk.Button(Frame1, text="Spara", command=self.file_save, width = 16)
button2.grid(column=0, row=8, sticky=(W, E), columnspan=4)
top1.update()
top1.resizable(width=False, height=False)
top1.mainloop()
def validate(self, action, index, value_if_allowed,
prior_value, text, validation_type, trigger_type, widget_name):
if text in '0123456789.-+':
try:
float(value_if_allowed)
return True
except ValueError:
return False
else:
return False
def file_save(self):
file = tk.filedialog.asksaveasfile(defaultextension=".txt", mode='wt', filetypes = (("txt files","*.txt"),("all files","*.*")))
if file:
data = self.text_entry.get('1.0', END+'-1c')
file.write(data)
file.close()
def funktion(self):
value1 = (self.a1.get())
value2 = (self.a2.get())
value3 = (self.a3.get())
value4 = (self.a4.get())
value5 = (self.a5.get())
for parts in range(value3-1, value5):
print('{}-{}-{}-{}\n'.format(value1, value2, parts+1, parts+1))
self.text_entry.insert(END, '{}-{}-{}-{}\n'.format(value1, value2, parts+1, parts+1))
self.a4.set('{}-{}-{}-{}\n'.format(value1, value2, parts+1, parts+1))
def close_windows(self):
self.master.destroy()
def main():
root = tk.Tk()
app = Demo1(root)
root.protocol("WM_DELETE_WINDOW")
root.mainloop()
if __name__ == '__main__':
main()

lucky for you I have way too much free time at the moment.
Try using:
self.a3.set("")
self.a5.set("")
maybe someone who actually knows tkinter will be able to help more.

I think you should try:
part1_entry.delete(0, 'end')
part2_entry.delete(0, 'end')

Related

Python tkinter : how to resize widgets when i resize the screen

I'm beginner...
When the code below is executed, how do I make the widgets inside increase when the screen size is increased to width? but, it couldn't resized..
Does it matter if I use either pack or grid?
i can't solve it....
from tkinter import *
from tkinter import ttk
class program:
def __init__(self):
self.root = Tk()
self.root.title("Python")
self.root.resizable(True, True)
self.create_project()
def create_project(self):
Topic_Label = ttk.Label(self.root, text="program")
Topic_Label.pack(side="top")
Record_LabelFrame = LabelFrame(self.root, text="Record information")
Record_LabelFrame.pack(side="top", anchor=W, padx=10)
date = ttk.Label(Record_LabelFrame, text="date")
date.grid(column=0, row=0, sticky=W)
Topic_Label_Entry1 = ttk.Entry(Record_LabelFrame)
Topic_Label_Entry1.grid(column=0, row=1)
time = ttk.Label(Record_LabelFrame, text="time")
time.grid(column=1, row=0, sticky=W)
Topic_Label_Combo1 = ttk.Combobox(Record_LabelFrame)
Topic_Label_Combo1.grid(column=1, row=1)
recorder = ttk.Label(Record_LabelFrame, text="record")
recorder.grid(column=2, row=0, sticky=W)
Topic_Label_Entry2 = ttk.Entry(Record_LabelFrame)
Topic_Label_Entry2.grid(column=2, row=1)
loc = ttk.Label(Record_LabelFrame, text="location")
loc.grid(column=0, row=2, sticky="W")
RadioVar = IntVar()
Radio_Frame = Frame(Record_LabelFrame)
Radio_Frame.grid(column=0, row=3, sticky=W)
Topic_Label_Radio1 = ttk.Radiobutton(Radio_Frame, text="A", variable=RadioVar, value=1)
Topic_Label_Radio1.grid(column=0, row=0)
Topic_Label_Radio2 = ttk.Radiobutton(Radio_Frame, text="B", variable=RadioVar, value=2)
Topic_Label_Radio2.grid(column=1, row=0)
Topic_Label_Radio3 = ttk.Radiobutton(Radio_Frame, text="C", variable=RadioVar, value=3)
Topic_Label_Radio3.grid(column=2, row=0)
count = ttk.Label(Record_LabelFrame, text="count")
count.grid(column=1, row=2, sticky="W")
Topic_Label_Combo2 = ttk.Combobox(Record_LabelFrame)
Topic_Label_Combo2.grid(column=1, row=3)
seed_name = ttk.Label(Record_LabelFrame, text="seed")
seed_name.grid(column=2, row=2, sticky="W")
Topic_Label_Entry4 = ttk.Entry(Record_LabelFrame)
Topic_Label_Entry4.grid(column=2, row=3)
mt = program()
mt.root.mainloop()
I want to print like this that widget resize automatically when i resize the screen
https://i.stack.imgur.com/iSbaJ.png
https://i.stack.imgur.com/mzv9R.png

Python Tkinter how to list down, but the newest element is on top

I am working on a little finance project. When I add to my balance, the entry gets listed among themselves. But I want to "change direction", so the newest entry is always on row 3 and the others lists among themselves. The problem is I don't know how to access to the other Elements to add to their row.
It should be something like that:
I entry a amount to add to the main balance- for example 40$
It gets shown on column 0, row 3
If I add another amount it should show on row 3- for example 20$, and the 40$ should move to row 4.
It should get listed like that:
row 3: 20$ ,
row 4: 40$
and so on..
Sorry for beginner mistakes, Im new to python :)
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
class App():
def __init__(self):
self.window = tk.Tk()
self.window.title("Expenses")
self.window.geometry("700x600")
self.window.resizable(0,0)
self.username_list = ["a"]
self.password_list = ["a"]
self.balace = 90
self.row_first_column = 2
self.start_frame()
self.window.mainloop()
def start_frame(self):
self.window.columnconfigure(0, weight=1)
self.window.columnconfigure(1, weight=1)
self.window.columnconfigure(2, weight=1)
self.heading_label = ttk.Label(self.window, text="Log-In", font=("", 25))
self.heading_label.grid(column=1, row=0, sticky=tk.NS, pady=40)
self.username = ttk.Label(self.window, text="Username:")
self.username.grid(column=1, row=1, sticky=tk.W, pady=30)
self.password = ttk.Label(self.window, text="Password:")
self.password.grid(column=1, row=2, sticky=tk.W)
self.entry1 = ttk.Entry(self.window)
self.entry1.grid(column=1, row=1)
self.entry2 = ttk.Entry(self.window)
self.entry2.grid(column=1, row=2)
self.warning = ttk.Label(self.window, text="")
self.warning.grid(column=1, row=3, sticky= tk.NS, pady=10)
self.button1 = ttk.Button(self.window, text="Submit", command= self.check_data)
self.button1.grid(column=1, row=4, sticky=tk.NS)
def check_data(self):
username_check = self.entry1.get()
password_check = self.entry2.get()
if username_check in self.username_list and password_check in self.password_list:
self.main_frame()
else:
self.warning.configure(text="Incorrect data! Try again")
self.entry2.delete(0, tk.END)
def main_frame(self):
self.username.destroy()
self.password.destroy()
self.entry1.destroy()
self.entry2.destroy()
self.warning.destroy()
self.button1.destroy()
self.heading_label.configure(text="Finance", font=("", 25))
#First Column
self.sub_heading1 = ttk.Label(self.window, text="Overview", font=("", 15))
self.sub_heading1.grid(column=0, sticky=tk.NS, row=1, pady=20)
self.balance_label = ttk.Label(self.window, text=f"{self.balace}$")
self.balance_label.grid(column=0, row=2, pady=20, sticky=tk.NS)
#Second Column
self.sub_heading2 = ttk.Label(self.window, text="Add", font=("", 15))
self.sub_heading2.grid(column=1, sticky=tk.NS, row=1, pady=20)
self.add_balance = ttk.Entry(self.window, width=5)
self.add_balance.grid(column=1, row=2, pady=20, sticky=tk.NS)
self.add_button = ttk.Button(self.window, text="Add",width=3, command= self.entry_add_balance)
self.add_button.grid(column=1, row=3, pady=10, sticky=tk.NS)
#Third Column
self.sub_heading3 = ttk.Label(self.window, text="Minus", font=("", 15))
self.sub_heading3.grid(column=2, sticky=tk.NS, row=1, pady=20)
def entry_add_balance(self):
addjust_balance_user = int(self.add_balance.get())
self.add_balance.delete(0, tk.END)
self.balace += addjust_balance_user
self.balance_label.configure(text=f"{self.balace}$")
#First Column
self.row_first_column += 1
new_add_label = ttk.Label(self.window, text=f"+{addjust_balance_user}$")
new_add_label.grid(column=0, row=self.row_first_column, pady=5,padx=15, sticky=tk.E)
app = App()

Display the location name of the open file in the tkinter window

Very simple, don't be impressed by the size of the code.
I want to do something very simple (well, not for me, since I'm asking for help here) put the location of the open file in the red square on the screen:
Screen
import tkinter as tk
from tkinter.filedialog import askopenfilename
from tkinter import messagebox
def OpenFile_AntiDuplicate():
global antiduplicate_file
mainframe = tk.Frame(bg='#1c2028')
antiduplicate_file = askopenfilename(initialdir="/",
filetypes =(("Text file", "*.txt"),("All files","*.*")),
title = "Open text file"
)
fichier_dir = tk.Label(mainframe, text=antiduplicate_file).pack()
try:
with open(antiduplicate_file,'r') as UseFile:
print(antiduplicate_file)
except:
print("Non-existent file")
def RUN_AntiDuplicate():
try:
with open(antiduplicate_file,'r') as UseFile:
print(antiduplicate_file)
except:
error1 = tk.messagebox.showerror("ERROR", "No files exist!")
#----------------------------------------------------------
class HoverButton(tk.Button):
def __init__(self, master, **kw):
tk.Button.__init__(self,master=master,**kw)
self.defaultBackground = self["background"]
self.bind("<Enter>", self.on_enter)
self.bind("<Leave>", self.on_leave)
def on_enter(self, e):
self['background'] = self['activebackground']
def on_leave(self, e):
self['background'] = self.defaultBackground
#----------------------------------------------------------
def Anti_Duplicate():
mainframe = tk.Frame(bg='#1c2028')
mainframe.grid(row=0, column=0, sticky='nsew')
bouton_1 = HoverButton(mainframe, font=("Arial", 10), text="Back",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#CF3411',
relief='ridge', command=mainframe.destroy)
bouton_1.place(x=520, y=300)
open_button = HoverButton(mainframe, font=("Arial", 10), text="Open File..",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf',
relief='ridge', command = OpenFile_AntiDuplicate)
open_button.place(x=284.3, y=200, anchor='n')
run_button = HoverButton(mainframe, font=("Arial", 20), text="RUN",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#11CF6D',
relief='ridge', command = RUN_AntiDuplicate)
run_button.place(x=50, y=330, anchor='s')
bouton_2 = tk.Button(mainframe, font=("Arial", 10),
text="The purpose of this tool is to remove duplicate lines from a text file.",
background='#202124', fg='#1195cf', borderwidth=2,
activebackground= '#202124', activeforeground='#1195cf', relief='sunken')
bouton_2.place(relx=.5, y=50, anchor='n')
bouton_1 = tk.Button(mainframe, font=("Arial", 15), text="Anti-Duplicate",
background='#202124', fg='#1195cf', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf', relief='sunken')
bouton_1.pack(side= "top", padx= 5, pady=5, ipadx= 30, anchor="n")
#----------------------------------------------------------
def main_menu():
root = tk.Tk()
screenn_x = int(root.winfo_screenwidth())
root.config(background='#1c2028')
screenn_y = int(root.winfo_screenheight())
root.title("ComboKit v0.0.1")
root.minsize(570, 340)
root.resizable(0,0)
windowss_x = 570
windowss_y = 340
possX = (screenn_x // 2) - (windowss_x // 2)
possY = (screenn_y // 2) - (windowss_y // 2)
geoo = "{}x{}+{}+{}".format(windowss_x, windowss_y, possX, possY)
root.geometry(geoo)
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
mainframe = tk.Frame(root, bg='#1c2028')
mainframe.grid(row=0, column=0, sticky='n')
main_fusion_bouton = HoverButton(mainframe, font=("Arial", 15), text="Fusion",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf',
relief='ridge', command=None)
main_fusion_bouton.pack(side= "left", padx= 5, pady=5, ipadx= 10, anchor="n")
main_antiduplicate_bouton = HoverButton(mainframe, font=("Arial", 15), text="Anti-Duplicate",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf',
relief='ridge', command=Anti_Duplicate)
main_antiduplicate_bouton.pack(side= "left", padx= 5, pady=5, ipadx= 30)
main_split_button = HoverButton(mainframe, font=("Arial", 15), text="Split",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf',
relief='ridge', command=None)
main_split_button.pack(side= "left", padx= 5, pady=5, ipadx= 19, anchor="n")
root.mainloop()
main_menu()
So here's my code allows you to use 3 tools:
"Split" / "Anti-Duplicate" / "Merge"
At the moment I'm working on the "Anti-Duplicate" so it's on this Frame() where the text should be displayed.
I've already done everything, even the button to open the file explorer, but for the moment the location of the file is only displayed in the cmd.
Thank you very much!
The location of the file does not show up because you created a new frame to hold the label fichier_dir inside OpenFile_AntiDuplicate() and you did not call any layout function on the frame, so the frame will not be shown.
Better create the label fichier_dir inside Anti_Duplicate() and pass it to OpenFile_AntiDuplicate() function:
def Anti_Duplicate():
...
fichier_dir = tk.Label(mainframe, bg='#1c2028', fg='white')
fichier_dir.place(relx=0.5, y=170, anchor='n')
open_button = HoverButton(mainframe, font=("Arial", 10), text="Open File..",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf',
relief='ridge', command = lambda: OpenFile_AntiDuplicate(fichier_dir))
...
And update OpenFile_AntiDuplicate(...):
def OpenFile_AntiDuplicate(fichier_dir):
global antiduplicate_file
antiduplicate_file = askopenfilename(initialdir="/",
filetypes =(("Text file", "*.txt"),("All files","*.*")),
title = "Open text file"
)
fichier_dir['text'] = antiduplicate_file
...

Tkinter won't close correctly and launch new file

I made a little login screen. After I put in the credentials I want the Tkinter to be closed and open a new python file. If you execute the code below it will give me the error NameError: name ttk is not defined. In the other file I imported everything and gave it the correct name.
The file I use for the login:
from tkinter import *
import tkinter.messagebox as tm
class LoginFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.label_username = Label(self, text="Username")
self.label_password = Label(self, text="Password")
self.photo = PhotoImage(file="sbshreg.png")
self.label_image = Label(root, image=self.photo)
self.label_image.image = self.photo
self.entry_username = Entry(self)
self.entry_password = Entry(self, show="*")
self.label_username.grid(row=0, sticky=E)
self.label_password.grid(row=1, sticky=E)
self.label_image.grid(row=3, column=2, rowspan=2, columnspan=2, sticky=W, padx=10)
self.entry_username.grid(row=0, column=1, sticky=E)
self.entry_password.grid(row=1, column=1, sticky=E)
self.logbtn = Button(self, text="Login", command=self._login_btn_clicked)
self.logbtn.grid(columnspan=2, column=1, row=2, sticky=S+E+N+W)
self.grid()
def _login_btn_clicked(self):
username = self.entry_username.get()
password = self.entry_password.get()
if username == "123" and password == "123":
tm.showinfo("SBSHREG", "Welcome 123")
#The sweet spot where all goes wrong...
self.destroy()
exec(open("./BatchFrame.py").read())
else:
tm.showerror("SBSHREG", "Incorrect username")
root = Tk()
root.title("SBSHREG")
root.geometry("235x120")
lf = LoginFrame(root)
root.mainloop()
In the other file I got this: from tkinter import ttk as ttk which should prevent the error in the other file from happening.
from tkinter import *
import tkinter.messagebox as tm
from tkinter import ttk as ttk
class BatchFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.photo = PhotoImage(file="sbshreg.png")
self.label_photo = Label(root, image=self.photo)
self.label_photo.image = self.photo
self.label_photo.grid(row=0, column=2, sticky=N, padx=10, pady=10)
#Add frame starting here
frame = LabelFrame(self.master, text='Voeg batch toe')
frame.grid (row=0, column=0, padx=10)
self.label_batch = Label(frame, text="Batchnummer")
self.label_employee = Label(frame, text="Medewerker")
self.label_material = Label(frame, text="Materiaalsoort")
self.label_weight = Label(frame, text="Gewicht")
self.entry_batch = Entry(frame)
self.entry_employee = Entry(frame)
self.entry_material= Entry(frame)
self.entry_weight = Entry(frame)
self.label_batch.grid(row=0, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.label_employee.grid(row=2, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.label_material.grid(row=4, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.label_weight.grid(row=6, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_batch.grid(row=1, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_employee.grid(row=3, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_material.grid(row=5, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_weight.grid(row=7, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.btnadd = Button(frame, text='Voeg toe', command=self._btn_add_clicked)
self.btnadd.grid(column=0, row=8, pady=10)
#Search frame starting here
framesearch = LabelFrame(self.master, text='Zoek')
framesearch.grid(row=0, column=1, sticky=N)
self.label_batch = Label(framesearch, text="Batchnummer")
self.label_employee = Label(framesearch, text="Medewerker")
self.entry_batch = Entry(framesearch)
self.entry_employee = Entry(framesearch)
self.label_batch.grid(row=0, column=0, sticky=S, columnspan=2, padx=10)
self.label_employee.grid(row=2, column=0, sticky=S, columnspan=2, padx=10)
self.entry_batch.grid(row=1, column=0, sticky=S + E + N + W, columnspan=2, padx=10, pady=10)
self.entry_employee.grid(row=3, column=0, sticky=S + E + N + W, columnspan=2, padx=10, pady=10)
self.btnbatch = Button(framesearch, text="Zoek", command=self._btn_batch_clicked)
self.btnemployee = Button(framesearch, text="Zoek", command=self._btn_employee_clicked)
self.btnbatch.grid(columnspan=1, column=2, row=1, sticky=W, padx=10)
self.btnemployee.grid(columnspan=1, column=2, row=3, sticky=W, padx=10)
#This is the viewingarea for the data
self.tree = ttk.Treeview (height=10, columns=("Batchnummer", "Medewerker", "Materiaalsoort", "Gewicht"))
self.tree.grid (row=9, columnspan=10, padx=10, pady=10)
self.tree.heading('#1', text='Batchnummer', anchor=W)
self.tree.heading('#2', text='Medewerker', anchor=W)
self.tree.heading('#3', text='Materiaalsoort', anchor=W)
self.tree.heading('#4', text='Gewicht', anchor=W)
self.tree.column('#0', stretch=NO, minwidth=0, width=0)
self.tree.column('#1', stretch=NO, minwidth=0, width=100)
self.tree.column('#2', stretch=NO, minwidth=0, width=100)
self.tree.column('#3', stretch=NO, minwidth=0, width=100)
self.tree.column('#4', stretch=NO, minwidth=0, width=100)
self.grid()
def _btn_add_clicked(self):
batch = self.entry_batch.get()
def _btn_batch_clicked(self):
batch = self.entry_batch.get()
def _btn_employee_clicked(self):
batch = self.entry_employee.get()
root = Tk()
root.title("SBSHREG")
root.geometry("432x480")
lf = BatchFrame(root)
root.mainloop()
If I change self.destroy() to root.destroy() I get the following error: _tkinter.TclError: can't invoke "label" command: application has been destroyed. In the second file the functions are not done yet because I'm still working on the file, but this shouldn't have any impact on the error.
I searched everywhere and tried a lot and I still got no clue whatsoever...
Consider initializing frames in a top level class, GUI, that handles opening of both frames where LoginFrame calls its parent's open_batch() (now lambda implemented) method. Below assumes LoginFrame.py and BatchFrame.py resides in same folder as GUI_App script.
In this way, scripts run as standalone modules on one Tk() instance.
GUIApp (calls child frames, LoginFrame, and BatchFrame)
from tkinter import *
import LoginFrame as LF
import BatchFrame as BF
class GUI():
def __init__(self):
self.root = Tk()
self.root.title("SBSHREG")
self.root.geometry("235x120")
self.root.open_batch = self.open_batch
lf = LF.LoginFrame(self.root)
self.root.mainloop()
def open_batch(self):
bf = BF.BatchFrame(self.root)
app = GUI()
LoginFrame
from tkinter import *
import tkinter.messagebox as tm
class LoginFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.label_username = Label(self, text="Username")
self.label_password = Label(self, text="Password")
self.photo = PhotoImage(file="sbshreg.png")
self.label_image = Label(self, image=self.photo)
self.label_image.image = self.photo
self.entry_username = Entry(self)
self.entry_password = Entry(self, show="*")
self.label_image.grid(row=0, column=2, rowspan=2, columnspan=2, sticky=W, padx=10)
self.label_username.grid(row=2, sticky=E)
self.label_password.grid(row=3, sticky=E)
self.entry_username.grid(row=2, column=1, sticky=E)
self.entry_password.grid(row=3, column=1, sticky=E)
self.logbtn = Button(self, text="Login", command=lambda: self._login_btn_clicked(master))
self.logbtn.grid(row=4, column=1, columnspan=2, sticky=S+E+N+W)
self.grid()
def _login_btn_clicked(self, controller):
username = self.entry_username.get()
password = self.entry_password.get()
if username == "123" and password == "123":
tm.showinfo("SBSHREG", "Welcome 123")
self.destroy()
controller.open_batch()
else:
tm.showerror("SBSHREG", "Incorrect username")
BatchFrame
from tkinter import *
import tkinter.messagebox as tm
from tkinter import ttk as ttk
class BatchFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.photo = PhotoImage(file="sbshreg.png")
self.label_photo = Label(master, image=self.photo)
self.label_photo.image = self.photo
self.label_photo.grid(row=0, column=2, sticky=N, padx=10, pady=10)
#Add frame starting here
frame = LabelFrame(master, text='Voeg batch toe')
frame.grid (row=0, column=0, padx=10)
self.label_batch = Label(frame, text="Batchnummer")
self.label_employee = Label(frame, text="Medewerker")
self.label_material = Label(frame, text="Materiaalsoort")
self.label_weight = Label(frame, text="Gewicht")
self.entry_batch = Entry(frame)
self.entry_employee = Entry(frame)
self.entry_material= Entry(frame)
self.entry_weight = Entry(frame)
self.label_batch.grid(row=0, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.label_employee.grid(row=2, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.label_material.grid(row=4, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.label_weight.grid(row=6, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_batch.grid(row=1, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_employee.grid(row=3, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_material.grid(row=5, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_weight.grid(row=7, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.btnadd = Button(frame, text='Voeg toe', command=self._btn_add_clicked)
self.btnadd.grid(column=0, row=8, pady=10)
#Search frame starting here
framesearch = LabelFrame(master, text='Zoek')
framesearch.grid(row=0, column=1, sticky=N)
self.label_batch = Label(framesearch, text="Batchnummer")
self.label_employee = Label(framesearch, text="Medewerker")
self.entry_batch = Entry(framesearch)
self.entry_employee = Entry(framesearch)
self.label_batch.grid(row=0, column=0, sticky=S, columnspan=2, padx=10)
self.label_employee.grid(row=2, column=0, sticky=S, columnspan=2, padx=10)
self.entry_batch.grid(row=1, column=0, sticky=S + E + N + W, columnspan=2, padx=10, pady=10)
self.entry_employee.grid(row=3, column=0, sticky=S + E + N + W, columnspan=2, padx=10, pady=10)
self.btnbatch = Button(framesearch, text="Zoek", command=self._btn_batch_clicked)
self.btnemployee = Button(framesearch, text="Zoek", command=self._btn_employee_clicked)
self.btnbatch.grid(columnspan=1, column=2, row=1, sticky=W, padx=10)
self.btnemployee.grid(columnspan=1, column=2, row=3, sticky=W, padx=10)
#This is the viewingarea for the data
self.tree = ttk.Treeview (height=10, columns=("Batchnummer", "Medewerker", "Materiaalsoort", "Gewicht"))
self.tree.grid (row=9, columnspan=10, padx=10, pady=10)
self.tree.heading('#1', text='Batchnummer', anchor=W)
self.tree.heading('#2', text='Medewerker', anchor=W)
self.tree.heading('#3', text='Materiaalsoort', anchor=W)
self.tree.heading('#4', text='Gewicht', anchor=W)
self.tree.column('#0', stretch=NO, minwidth=0, width=0)
self.tree.column('#1', stretch=NO, minwidth=0, width=100)
self.tree.column('#2', stretch=NO, minwidth=0, width=100)
self.tree.column('#3', stretch=NO, minwidth=0, width=100)
self.tree.column('#4', stretch=NO, minwidth=0, width=100)
self.grid()
def _btn_add_clicked(self):
batch = self.entry_batch.get()
def _btn_batch_clicked(self):
batch = self.entry_batch.get()
def _btn_employee_clicked(self):
batch = self.entry_employee.get()
I do not agree with the method of how you are invoking your 2nd python file.
You really dont need to use exec here.
However if you really want to you need to add import tkinter.ttk as ttk to your first page for it to work right.
Your best option is to import the 2nd file on the 1st file and invoke it by calling the class name.
so for you imports on the first page you need to add import BatchFrame.
Then call it in your code.
Replace:
exec(open("./test2.py").read())
with:
BatchFrame.BatchFrame(root)
I do see one mistake in your BatchFrame class thought.
change this:
self.label_photo = Label(root, image=self.photo)
to this:
self.label_photo = Label(master, image=self.photo)
UPDATE:
To address your issue from the comment make these changes:
1: Add this to your BatchFrame Class:
class BatchFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.master = master # add this
self.master.title("SBSHREG") # and this
self.master.geometry("432x480") # and this
2: Remove this from your BatchFrame file:
root = Tk()
root.title("SBSHREG")
root.geometry("432x480")
lf = BatchFrame(root)
root.mainloop()
3: Add this to your LoginFrame class:
class LoginFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.master = master # add this
4: In the LoginFrame class change this:
BatchFrame.BatchFrame(root)
to this:
BatchFrame.BatchFrame(self.master)
I recommend importing batchframe instead of executing it.
from tkinter import *
import tkinter.messagebox as tm
from tkinter import ttk as ttk
from batchframe import BatchFrame
class LoginFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.master = master
self.label_username = Label(self, text="Username")
self.label_password = Label(self, text="Password")
self.photo = PhotoImage(file="icon.png")
self.label_image = Label(root, image=self.photo)
self.label_image.image = self.photo
self.entry_username = Entry(self)
self.entry_password = Entry(self, show="*")
self.label_username.grid(row=0, sticky=E)
self.label_password.grid(row=1, sticky=E)
self.label_image.grid(row=3, column=2, rowspan=2, columnspan=2, sticky=W, padx=10)
self.entry_username.grid(row=0, column=1, sticky=E)
self.entry_password.grid(row=1, column=1, sticky=E)
self.logbtn = Button(self, text="Login", command=self._login_btn_clicked)
self.logbtn.grid(columnspan=2, column=1, row=2, sticky=S+E+N+W)
self.grid()
def _login_btn_clicked(self):
username = self.entry_username.get()
password = self.entry_password.get()
if username == "123" and password == "123":
tm.showinfo("SBSHREG", "Welcome 123")
#The sweet spot where all goes wrong...
self.destroy()
# Create the instance of the BatchFrame class, passing in self.master
self.batchframe = BatchFrame(self.master)
else:
tm.showerror("SBSHREG", "Incorrect username")
Then in batchframe.py change variable reference from root to master

Scrollable frame will not render all items in it Python Tkinter

I am working on a program where there is a scrollable frame that will be containing a large quantity of items. But with my app it does not render all of them. Can someone possibly tell me why? And how I can fix it?
Code:
#700x650
from Tkinter import *
import ttk
class itemLoad:
def __init__(self):
pass
def item(self):
items = "Video File,Image File,None,King King"
return items
class App(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.pack(fill=BOTH)
self.loadItem = itemLoad()
self.one = None
self.create_widgets()
self.loadItems()
def create_widgets(self):
self.mainFrame = Frame(self, width=700, height=650)
self.mainFrame.pack_propagate(False)
self.mainFrame.pack()
self.menu = Frame(self.mainFrame, width=150, height=650, bg="Gray92")
self.menu.pack_propagate(False)
self.menu.pack(side=LEFT)
self.itemMenu = Frame(self.mainFrame, width=550, height=650)
self.itemMenu.pack_propagate(False)
self.itemMenu.pack(side=LEFT)
self.vScroller = ttk.Scrollbar(self.itemMenu, orient=VERTICAL)
self.vScroller.pack(side=RIGHT, fill=Y)
self.canvas = Canvas(self.itemMenu, bd=0, width=534, highlightthickness=0, yscrollcommand=self.vScroller.set)
self.canvas.pack_propagate(False)
self.canvas.pack(side=LEFT, fill=BOTH)
self.vScroller.config(command=self.canvas.yview)
self.innerFrame = Frame(self.canvas, width=550, height=650, bg="Pink")
self.canvas.create_window(0, 0, window=self.innerFrame, anchor=NW)
def update(event):
self.canvas.config(scrollregion=self.canvas.bbox("all"))
self.innerFrame.bind("<Configure>", update)
self.spacer = Frame(self.mainFrame, bg="Gray")
self.spacer.pack(side=LEFT, fill=Y)
frame = Frame(self.menu, bg="Gray92")
frame.pack(side=TOP, fill=X)
high = Frame(frame, bg="Gray92", width=10)
high.pack(side=LEFT, fill=Y)
self.bu1 = Label(frame, font=("Calibri", 14), text=" Main Folder", width=12, anchor=W, bg="Gray92")
self.bu1.pack(side=LEFT, fill=X, ipadx=10, ipady=10)
frame2 = Frame(self.menu, bg="Gray92")
frame2.pack(side=TOP, fill=X)
high2 = Frame(frame2, bg="Gray92", width=10)
high2.pack(side=LEFT, fill=Y)
self.bu2 = Label(frame2, font=("Calibri", 14), text=" Favorited", width=12, anchor=W, bg="Gray92")
self.bu2.pack(side=LEFT, fill=X, ipadx=10, ipady=10)
frame3 = Frame(self.menu, bg="Gray92")
frame3.pack(side=TOP, fill=X)
high3 = Frame(frame3, bg="Gray92", width=10)
high3.pack(side=LEFT, fill=Y)
self.bu3 = Label(frame3, font=("Calibri", 14), text=" Trash Can", width=12, anchor=W, bg="Gray92")
self.bu3.pack(side=LEFT, fill=X, ipadx=10, ipady=10)
frame4 = Frame(self.menu, bg="Gray92")
frame4.pack(side=BOTTOM, fill=X)
high4 = Frame(frame4, bg="Gray92", width=10)
high4.pack(side=LEFT, fill=Y)
self.bu4 = Label(frame4, font=("Calibri", 14), text=" Log Out", width=12, anchor=W, bg="Gray92")
self.bu4.pack(side=LEFT, fill=X, ipadx=10, ipady=10)
def hover(event):
widg = event.widget
items = widg.winfo_children()
if items[1].cget("text") == self.one:
pass
else:
items[0].config(bg="Gray85")
items[1].config(bg="Gray85")
def unHover(event):
widg = event.widget
text = None
items = widg.winfo_children()
if items[1].cget("text") == self.one:
pass
else:
items[0].config(bg="Gray92")
items[1].config(bg="Gray92")
def clicked(event):
widg = event.widget
par = widg.winfo_parent()
par = self.menu._nametowidget(par)
for item in self.menu.winfo_children():
items = item.winfo_children()
items[0].config(bg="Gray92")
for item in par.winfo_children():
try:
self.one = item.cget("text")
except:
item.config(bg="lightBlue")
frame.bind("<Enter>", hover)
frame2.bind("<Enter>", hover)
frame3.bind("<Enter>", hover)
frame4.bind("<Enter>", hover)
frame.bind("<Leave>", unHover)
frame2.bind("<Leave>", unHover)
frame3.bind("<Leave>", unHover)
frame4.bind("<Leave>", unHover)
high.bind("<Button-1>", clicked)
self.bu1.bind("<Button-1>", clicked)
high2.bind("<Button-1>", clicked)
self.bu2.bind("<Button-1>", clicked)
high3.bind("<Button-1>", clicked)
self.bu3.bind("<Button-1>", clicked)
high4.bind("<Button-1>", clicked)
self.bu4.bind("<Button-1>", clicked)
def loadItems(self):
theItems = self.loadItem.item()
for i in range(0, 500):
none = Frame(self.innerFrame, width=200, height=500, bg="red")
none.pack_propagate(False)
none.pack(side=TOP, padx=10, pady=10)
let = Label(none, text=i)
let.pack(side=TOP)
root = Tk()
root.geometry("700x650")
root.resizable(0,0)
app = App(root)
root.mainloop()
I think you're exceeding the limits of the tkinter canvas. The frame you're trying to scroll is 250,000 pixels tall. I doubt the canvas can handle that.
When I make all of your inner widgets considerably smaller your code works fine.

Categories