Related
Basically I have a class that inherits from LabelFrame, I want it to show up on the window itself, but I don't see it at all, it doesn't even show up on the window no matter what I do
from tkinter import *
root = Tk()
root['bg'] = 'white'
root.state('zoomed')
class CharacterFrame(LabelFrame):
def __init__(self, master, skin_img, requirement, desc):
super().__init__(master=master, bg='grey29')
self.desc = Label(self, text=desc)
default_char_frame = CharacterFrame(master=root, desc='Default Character.', requirement=0, skin_img='')
default_char_frame.grid(row=0, column=0, sticky='nse')
root.mainloop()
ok, so i was stupid for not implementing the actual code itself, but ill do it now (This isnt actual source code, just the important code, still has same error as actual code):
from tkinter import *
root = Tk()
root['background'] = 'white'
root.state('zoomed')
class SkinFrame(LabelFrame):
def __init__(self, master, skin_img, requirement, desc):
super().__init__(master=master, bg='grey29')
self.desc = Label(self, text=desc)
self.desc.pack()
def show_chars():
button_grid.grid_forget()
skin_lib.grid(row=1, column=0, sticky='nws')
button_skin0 = Button(skin_lib, text="Skin1", relief="flat", width=15, fg="white", bg="darkgrey", command=lambda: show_char_frame(prev, default_char_frame), font=("Arial", 29, "italic"))
button_skin0.grid(row=0, column=0, pady=(0,10))
back = Button(skin_lib, text="Back", width=15, relief="flat", fg="white", bg="maroon", font=("Arial",29,"italic"),
command=lambda: [skin_lib.grid_forget(), button_grid.grid(row=1, column=0, sticky='nws')])
back.grid(row=100, column=0)
def show_char_frame(prev, char_frame):
skin_lib.grid_forget()
default_char_frame.grid(row=1, column=1, sticky='nse')
default_char_frame = SkinFrame(master=root, desc='Default Skin.', requirement=0, skin_img='')
Label(root, text="Game Title", width=68, relief="flat", bg="white", fg="grey", font=("Arial",26,"italic")).grid(row=0, column=0, sticky='n')
button_grid = LabelFrame(root, bg='grey29', relief="groove", pady=10, padx=10)
button_grid.grid(row=1, column=0, sticky='nws')
skin_lib = LabelFrame(root, bg='grey29', relief="groove", pady=10, padx=10)
skins = Button(button_grid, text="Skins", width=15, relief="flat", fg="white", bg="navy", command=show_chars, font=("Arial", 29, "italic"))
skins.grid(row=2, column=0, pady=(0,10))
previous_skinframe
root.mainloop()
you missed to pack() label to add in control
self.desc.pack()
this is complete code
from tkinter import *
root = Tk()
root['bg'] = 'white'
root.state('zoomed')
class CharacterFrame(LabelFrame):
def __init__(self, master, skin_img, requirement, desc):
super().__init__(master=master, bg='grey29')
self.desc = Label(self, text=desc)
self.desc.pack()
default_char_frame = CharacterFrame(master=root, desc='Default Character.', requirement=0, skin_img='')
default_char_frame.grid(row=0, column=0, sticky='nse')
root.mainloop()
in this code what I add self.desc.pack() to show
this is output
So i have written a simple tkinter gui that will show some command output results when prompted, only issue i'm having is the command wont appear on any other screen.
def updateipt():
text = Text(main_window, height=150, width=124)
text.pack()
with Popen(["iptables", '-L', '-v', '-n'], stdout=PIPE, stderr=PIPE) as p:
for line in p.stdout:
text.insert(END, line,)
text = Text(main_window, height=150, width=124)
i assumed that replacing the main_window argument above with another window would direct the text widget to a different window, but everytime i try this i get an error Which states that the window needs to be Tk(): AttributeError: 'function' object has no attribute 'tk'
How do i work around this?
Full code posted below:
#!/bin/bash
import os
import subprocess as sub
from tkinter import *
from subprocess import Popen, PIPE
def main_window():
global main_window
main_window = Tk()
main_window.title("Firewall test")
main_window.geometry("1000x700")
main_window.configure(bg="dark grey")
label1 = Label(main_window, text="What Would you like to configure?", font=('arial', 12, 'bold'), bg="white",
fg="black")
label1.pack(fill=X, pady=20)
btnproc = Button(main_window, text="Process configuration", font=('arial', 9, 'bold'), bg="light grey", fg="black",
width="30", height="2", command=lambda: process_window())
btnproc.pack(pady=20)
btnfw = Button(main_window, text="Firewall", font=('arial', 9, 'bold'), bg="light grey", fg="black", width="30",
height="2", command=lambda: firewall_window())
btnfw.pack(pady=20)
btnmon = Button(main_window, text="AIDE", font=('arial', 9, 'bold'), bg="light grey", fg="black", width="30",
height="2", command=lambda: monitor_window())
btnmon.pack(pady=20)
main_window.mainloop()
def process_window():
global process_window
process_window = Toplevel(main_window)
process_window.title("Process Configuration")
process_window.geometry("800x600")
process_window.configure(bg="dark grey")
label1 = Label(process_window, text="What Would you like to configure?", font=('arial', 12, 'bold'), bg="white",
fg="black")
label1.pack(fill=X, pady=20)
def firewall_window():
firewall_window = Toplevel(main_window)
firewall_window.title("Firewall Configuration")
firewall_window.geometry("1000x600")
firewall_window.configure(bg="dark grey")
label1 = Label(firewall_window, text="What Would you like to configure?", font=('arial', 12, 'bold'), bg="white",
fg="black")
label1.pack(fill=X, pady=20)
updatebtn = Button(firewall_window, text="View Current Iptables layout", font=('arial', 9, 'bold'), bg="light grey",
fg="black", width="30",
height="2", command=lambda: updateipt())
updatebtn.pack(pady=20)
def monitor_window():
monitor_window = Toplevel(main_window)
monitor_window.title("AIDE Configuration")
monitor_window.geometry("800x600")
monitor_window.configure(bg="dark grey")
label1 = Label(monitor_window, text="What Would you like to configure?", font=('arial', 12, 'bold'), bg="white",
fg="black")
label1.pack(fill=X, pady=20)
def updateipt():
text = Text(firewall_window, height=150, width=124)
text.pack()
with Popen(["iptables", '-L', '-v', '-n'], stdout=PIPE, stderr=PIPE) as p:
for line in p.stdout:
text.insert(END, line,)
main_window()
In your code, the name of your functions are also the name of your windows (Toplevel). Please change all your function names. Also, in your updateipt function, you are giving a function to place the Text widget so it throws an error.
import os
import subprocess as sub
from tkinter import *
from subprocess import Popen, PIPE
def main_windows():
global main_window
main_window = Tk()
main_window.title("Firewall test")
main_window.geometry("1000x700")
main_window.configure(bg="dark grey")
label1 = Label(main_window, text="What Would you like to configure?", font=('arial', 12, 'bold'), bg="white",
fg="black")
label1.pack(fill=X, pady=20)
btnproc = Button(main_window, text="Process configuration", font=('arial', 9, 'bold'), bg="light grey", fg="black",
width="30", height="2", command=lambda: process_windows())
btnproc.pack(pady=20)
btnfw = Button(main_window, text="Firewall", font=('arial', 9, 'bold'), bg="light grey", fg="black", width="30",
height="2", command=lambda: firewall_windows())
btnfw.pack(pady=20)
btnmon = Button(main_window, text="AIDE", font=('arial', 9, 'bold'), bg="light grey", fg="black", width="30",
height="2", command=lambda: monitor_windows())
btnmon.pack(pady=20)
main_window.mainloop()
def process_windows():
global process_window
process_window = Toplevel()
process_window.title("Process Configuration")
process_window.geometry("800x600")
process_window.configure(bg="dark grey")
label1 = Label(process_window, text="What Would you like to configure?", font=('arial', 12, 'bold'), bg="white",
fg="black")
label1.pack(fill=X, pady=20)
def firewall_windows():
firewall_window = Toplevel()
firewall_window.title("Firewall Configuration")
firewall_window.geometry("1000x600")
firewall_window.configure(bg="dark grey")
label1 = Label(firewall_window, text="What Would you like to configure?", font=('arial', 12, 'bold'), bg="white",
fg="black")
label1.pack(fill=X, pady=20)
updatebtn = Button(firewall_window, text="View Current Iptables layout", font=('arial', 9, 'bold'), bg="light grey",
fg="black", width="30",
height="2", command=lambda: updateipt())
updatebtn.pack(pady=20)
def monitor_windows():
monitor_window = Toplevel(main_window)
monitor_window.title("AIDE Configuration")
monitor_window.geometry("800x600")
monitor_window.configure(bg="dark grey")
label1 = Label(monitor_window, text="What Would you like to configure?", font=('arial', 12, 'bold'), bg="white",
fg="black")
label1.pack(fill=X, pady=20)
def updateipt():
text = Text(main_window, height=150, width=124)
text.pack()
with Popen(["iptables", '-L', '-v', '-n'], stdout=PIPE, stderr=PIPE) as p:
for line in p.stdout:
text.insert(END, line)
main_windows()
Novel was kind enough to help me with hiding a frame until a checkbutton was checked.
it worked great, when script was run frame 3 defaulted to hidden.
My problem developed when I added another function to hide frame 4.
Now when I run sript frames are no longer defaulted to hidden.
I need to check and uncheck button to hide frame(S)
I have tried bundling all if variables under 1 def and the result is the same.
My actual command frame has 21 buttons that open 21 frames and it will work with a little help.
This is well above my level, but I am willing to learn
Any help would be greatly appreciated.
I have attached a shortened version of my final file.
from tkinter import *
from tkinter import Tk
import tkinter as tk
from tkinter import ttk
root=tk.Tk()
root.title("Dental Milling Machines")
root.geometry("1000x900")
def frame3_disp():
if cb_var1.get():
frame3.grid(row=2, column=0, pady=2,sticky="NW")
else:
frame3.grid_forget()
def frame4_disp():
if cb_var2.get():
frame4.grid(row=3, column=0, pady=2,sticky="NW")
else:
frame4.grid_forget()
cb_var1 = tk.IntVar()
cb_var2 = tk.IntVar()
frame1 = Frame(root, height = 150, width= 150, relief= RAISED, bd=8, bg="blue")
frame2 = Frame(frame1, height = 150, width= 150, relief= RAISED, bd=8, bg="lightblue")
frame3 = Frame(frame1, height = 150, width= 150, relief= RAISED, bd=8, bg="lightblue")
frame4 = Frame(frame1, height = 150, width= 150, relief= RAISED, bd=8, bg="lightblue")
label = Label(frame2, text="COMMAND FRAME", fg="red")
label.grid(row=0, columnspan=3, pady= 1, sticky= "W")
label = Label(frame3, text="FRAME 3", fg="red")
label.grid(row=0, columnspan=3, pady= 1, sticky= "W")
label = Label(frame4, text="FRAME 4", fg="red")
label.grid(row=0, columnspan=3, pady= 1, sticky= "W")
frame1.grid(row=0, column=0, pady=2,sticky="NW")
frame2.grid(row=1, column=0, pady=2,sticky="NW")
frame3.grid(row=2, column=0, pady=2,sticky="NW")
frame4.grid(row=3, column=0, pady=2,sticky="NW")
c1 = Checkbutton(frame2, text = "Unhide frame3 when checked HIDE when unchecked ", variable=cb_var1, command=frame3_disp)
c1.grid(row=1, column=0, pady= 1, padx= 5, sticky= "W")
c2 = Checkbutton(frame2, text = "Unhide frame4 when checked HIDE when unchecked ", variable=cb_var2, command=frame4_disp)
c2.grid(row=2, column=0, pady= 1, padx= 5, sticky= "W")
root.mainloop()
You should not call grid(...) on frame3 and frame4 after creating them if you want them hidden initially:
import tkinter as tk
from tkinter import ttk
root=tk.Tk()
root.title("Dental Milling Machines")
root.geometry("1000x900")
def frame3_disp():
if cb_var1.get():
frame3.grid(row=2, column=0, pady=2, sticky="NW")
else:
frame3.grid_forget()
def frame4_disp():
if cb_var2.get():
frame4.grid(row=3, column=0, pady=2, sticky="NW")
else:
frame4.grid_forget()
cb_var1 = tk.IntVar()
cb_var2 = tk.IntVar()
frame1 = tk.Frame(root, height=150, width=150, relief=tk.RAISED, bd=8, bg="blue")
frame2 = tk.Frame(frame1, height=150, width=150, relief=tk.RAISED, bd=8, bg="lightblue")
frame3 = tk.Frame(frame1, height=150, width=150, relief=tk.RAISED, bd=8, bg="lightblue")
frame4 = tk.Frame(frame1, height=150, width=150, relief=tk.RAISED, bd=8, bg="lightblue")
label = tk.Label(frame2, text="COMMAND FRAME", fg="red")
label.grid(row=0, columnspan=3, pady= 1, sticky= "W")
label = tk.Label(frame3, text="FRAME 3", fg="red")
label.grid(row=0, columnspan=3, pady= 1, sticky= "W")
label = tk.Label(frame4, text="FRAME 4", fg="red")
label.grid(row=0, columnspan=3, pady= 1, sticky= "W")
frame1.grid(row=0, column=0, pady=2,sticky="NW")
frame2.grid(row=1, column=0, pady=2,sticky="NW")
#frame3.grid(row=2, column=0, pady=2,sticky="NW")
#frame4.grid(row=3, column=0, pady=2,sticky="NW")
c1 = tk.Checkbutton(frame2, text = "Unhide frame3 when checked HIDE when unchecked ", variable=cb_var1, command=frame3_disp)
c1.grid(row=1, column=0, pady= 1, padx= 5, sticky= "W")
c2 = tk.Checkbutton(frame2, text = "Unhide frame4 when checked HIDE when unchecked ", variable=cb_var2, command=frame4_disp)
c2.grid(row=2, column=0, pady= 1, padx= 5, sticky= "W")
root.mainloop()
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
...
This is the class I'm calling and the function from a different file
class CalcFunc:
def clearScreen(self):
self.log("CLEAR (CE)")
ent.delete(0, END)
This is the Entry Box
ent = Entry(root, textvariable=clc.getBtn, justify=RIGHT, font=10, relief=RIDGE, bd=2, width=15)
ent.grid(row=0, columnspan=3, pady=10)
This is the button I'm clicking to clear the Entry Box
buttonCC = Button(root, text="CLEAR (CE)", height=1, width=20, bg='orange', command=clc.clearScreen)
I'm not sure what the syntax is to be able to to clear an Entry widget from a class basically. That code worked when I had it in the same file but my project requires it to be in a separate file. It's a class project for a calculator and the "clear" button clears the Entry widget. I can post my entire code if that helps. Thank you.
----EDIT----
My Class
import time
class CalcFunc:
def log(self, val):
myFile = open(r".\log.dat", "a")
myFile.write("%s\n" % val)
myFile.close()
def onScreen(self, iVal):
self.log(iVal)
currentTxt = self.getBtn.get()
updateEnt = self.getBtn.set(currentTxt + iVal)
def clearScreen(self):
self.log("CLEAR (CE)")
ent.delete(0, END)
def evaL(self):
self.log("=")
self.getBtn.set(str(eval(self.getBtn.get())))
self.log(self.getBtn.get())
def logLbl(self):
myFile = open(r".\log.dat", "a")
myFile.write("\n==================================\n")
myFile.write("Date: " + str(time.strftime("%m/%d/%Y")) + " -- Time: " + str(time.strftime("%I:%M:%S")))
myFile.write("\n==================================\n")
myFile.close()
My Program
from tkinter import *
import time
import clcClass
root = Tk()
root.title('skClc v1')
clc = clcClass.CalcFunc()
clc.logLbl()
clc.getBtn = StringVar()
ent = Entry(root, textvariable=clc.getBtn, justify=RIGHT, font=10, relief=RIDGE, bd=2, width=15)
ent.grid(row=0, columnspan=3, pady=10)
button1 = Button(root, text="1", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('1'))
button2 = Button(root, text="2", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('2'))
button3 = Button(root, text="3", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('3'))
button4 = Button(root, text="4", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('4'))
button5 = Button(root, text="5", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('5'))
button6 = Button(root, text="6", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('6'))
button7 = Button(root, text="7", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('7'))
button8 = Button(root, text="8", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('8'))
button9 = Button(root, text="9", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('9'))
button0 = Button(root, text="0", height=1, width=5, bg='light blue', command=lambda:onScreen('0'))
buttonP = Button(root, text="+", height=1, width=5, bg='gray', command=lambda:clc.onScreen('+'))
buttonM = Button(root, text="-", height=1, width=5, bg='gray', command=lambda:clc.onScreen('-'))
buttonMM = Button(root, text="x", height=1, width=5, bg='gray', command=lambda:clc.onScreen('*'))
buttonDD = Button(root, text="รท", height=1, width=5, bg='gray', command=lambda:clc.onScreen('/'))
buttonEE = Button(root, text="=", height=1, width=5, bg='light green', command=clc.evaL)
buttonCC = Button(root, text="CLEAR (CE)", height=1, width=20, bg='orange', command=clc.clearScreen)
button1.grid(row=1, column=0, pady=5)
button2.grid(row=1, column=1, pady=5)
button3.grid(row=1, column=2, pady=5)
button4.grid(row=2, column=0, pady=5)
button5.grid(row=2, column=1, pady=5)
button6.grid(row=2, column=2, pady=5)
button7.grid(row=3, column=0, pady=5)
button8.grid(row=3, column=1, pady=5)
button9.grid(row=3, column=2, pady=5)
button0.grid(row=4, column=0, pady=5)
buttonP.grid(row=4, column=1, pady=5)
buttonM.grid(row=4, column=2, pady=5)
buttonEE.grid(row=5, column=0, pady=5)
buttonDD.grid(row=5, column=1, pady=5)
buttonMM.grid(row=5, column=2, pady=5)
buttonCC.grid(row=6, column=0, pady=5, columnspan=3)
root.maxsize(140,245);
root.minsize(140,245);
root.mainloop()
ent = Entry(root, ....)
clc = clcClass.CalcFunc(ent)
class CalcFunc:
def __init__(self, entry):
self.entry = entry
def clearScreen(self):
self.log("CLEAR (CE)")
self.entry.delete(0, END)
Here's an abbreviated example:
#my_entry.py
from tkinter import END
import time
class EntryWithLogger:
def __init__(self, entry):
self.entry = entry
def log(self, val):
with open("log.dat", "a") as my_file: #Automatically closes the file--even if an exception occurs, which is not the case with my_file.close().
my_file.write("%s\n" % val)
def onScreen(self, i_val):
self.log(i_val)
self.entry.insert(END, i_val)
def clearScreen(self):
self.log("CLEAR (CE)")
self.entry.delete(0, END)
Note that I didn't use a StringVar(), which doesn't appear to be necessary. If you need it, you can always pass it as an argument to __init__(), then store it on self.
import my_entry as me
import tkinter as tk
root = tk.Tk()
root.title("Calculator")
root.geometry("+100+50") #("300x500+200+10") dimension, position
entry = tk.Entry(root, justify=tk.RIGHT, font=10, relief=tk.RIDGE, bd=2, width=15)
entry.grid(row=0, columnspan=3, pady=10)
entry_with_logger = me.EntryWithLogger(entry)
#Create the buttons in a loop:
for i in range(10):
row_num, col_num = divmod(i, 3) #divmod(7, 2) => (3, 1), divmod(0, 3) => (0, 0), divmod(4, 3) => (1, 1)
row_num += 1
button_text = str(i)
tk.Button(root, text=button_text,
height=1,
width=5,
bg='light blue',
command=lambda x=button_text: entry_with_logger.onScreen(x)
).grid(row=row_num, column=col_num, pady=5)
#Put the clear button at the bottom of the grid:
tk.Button(root, text="CLEAR (CE)",
height=1,
width=20,
bg='orange',
command=entry_with_logger.clearScreen
).grid(row=row_num+1, columnspan=3) #columnspan tells grid() to use 3 cells for the button,
#and the button will be centered by default.
root.mainloop()
Or, you could do it like this:
#my_entry.py
from tkinter import Entry, END
import time
class EntryWithLogger(Entry):
#Because __init__() is not implemented, the parent class's __init__() gets
#called, so you create an EntryWithLogger just like you would an Entry.
def log(self, val):
with open("log.dat", "a") as my_file: #Automatically closes the file--even if there is an exception, which is not the case with my_file.close().
my_file.write("%s\n" % val)
def onScreen(self, i_val):
self.log(i_val)
self.insert(END, i_val)
def clearScreen(self):
self.log("CLEAR (CE)")
self.delete(0, END)
import my_entry as me
import tkinter as tk
root = tk.Tk()
root.title("Calculator")
root.geometry("+100+50") #("300x500+200+10") dimension, position
entry = me.EntryWithLogger(root, justify=tk.RIGHT, font=10, relief=tk.RIDGE, bd=2, width=15)
entry.grid(row=0, columnspan=3, pady=10)
#Create the buttons in a loop:
for i in range(10):
row_num, col_num = divmod(i, 3) #divmod(7, 2) => (3, 1), divmod(0, 3) => (0, 0), divmod(4, 3) => (1, 1)
row_num += 1
button_text = str(i)
tk.Button(root, text=button_text,
height=1,
width=5,
bg='LightBlue',
command=lambda x=button_text: entry.onScreen(x)
).grid(row=row_num, column=col_num, pady=5)
#Put the clear button at the bottom of the grid:
tk.Button(root, text="CLEAR (CE)",
height=1,
width=20,
bg='orange',
command=entry.clearScreen
).grid(row=row_num+1, columnspan=3) #columnspan tells grid() to use 3 cells for the button,
#and the button will be centered by default.
root.mainloop()