Tkinter background color change alone - python-3.x

i'm doing a tkinter application, and i have this problem:
I have a Frame with this code:
class SelectFrame(customtkinter.CTkFrame):
def __init__(self, master, back):
super(SelectFrame, self).__init__(master)
self.configure(width=120, height=60, border_width=2,)
self.master = master
self.menu = ""
self.input = ""
self.back = back
self.create_widgets()
def create_widgets(self):
def segmented_button_callback(value):
if value == "Menu":
import menu_frame
self.menu = menu_frame.MenuFrame(self.master, self.back).place(x=25, y=125)
if value == "Inputs":
import input_frame
self.input = input_frame.InputFrame(self.master, self.back).place(x=25, y=125)
segemented_button = customtkinter.CTkSegmentedButton(master=self,
values=["Menu", "Inputs"],
command=segmented_button_callback,
width=100,
height=40,
selected_hover_color="blue",
font=("Helvetica", 14))
segemented_button.place(x=10, y=10)
The idea its that, when you click on Menu it creates a Menu Frame, and the same with the Input Frame.
The problem is that when i click on Input Frame, the background becomes white.
Here's the input frame code:
class InputFrame(customtkinter.CTkFrame):
# CONSTRUCTOR FOR THE CLASS
def __init__(self, master, back):
super(InputFrame, self).__init__(master)
self.master = master
self.configure(width=850, height=350)
self.table = ttk.Treeview(self, columns=("c1", "c2"), show='headings')
self.lbl_error = customtkinter.CTkLabel(master=self.master, text="", text_color="red")
self.style()
self.back = back
self.createWidgets()
# METHOD TO CHANGE THE STYLE OF THE TREEVIEW
def style(self):
# STYLE FOR TABLE
style = ttk.Style()
style.configure("Treeview",
background="#2a2d2e",
foreground="white",
fieldbackground="#343638",
bordercolor="#343638",
rowheight=35,
borderwidth=0,
font=(None, 16))
style.map('Treeview', background=[('selected', '#22559b')])
style.configure("Treeview.Heading",
background="#565b5e",
foreground="white",
font=(None, 16))
style.map("Treeview.Heading",
background=[('active', '#3484F0')])
# METHOD TO CREATE THE WIDGETS
def createWidgets(self):
"""logging.basicConfig(format='%(asctime)s.%(msecs)03d %(levelname)s {%(module)s} [%(funcName)s] %(message)s',
datefmt='%Y-%m-%d,%H:%M:%S', level=logging.DEBUG)
logging.info("start")"""
# TITLE FOR MOD 2
lbl_mod2 = customtkinter.CTkLabel(master=self, text="INPUTS INFO", font=("Helvetica", 16))
lbl_mod2.place(x=380, y=10)
# CREATING TABLE TO VIEW INPUT'S DATA
self.table['columns'] = ('input', 'pulses')
# DEFINITION OF COLUMNS
self.table.column("input", width=300, anchor="center")
self.table.column("pulses", width=500, anchor="center")
# HEADERS
self.table.heading("input", text="INPUT")
self.table.heading("pulses", text="Nº PULSES")
self.updateData()
self.table.place(x=225, y=60)
# LABEL FOR ERROR
self.lbl_error.place(x=180, y=430)
# METHOD TO UPDATE ALL THE DATA EVERY SECOND, AND WHEN PRESS REFRESH BUTTON
def updateData(self):
self.table.delete(*self.table.get_children())
pulses = []
try:
pulses = self.back.get_pulses()
self.lbl_error.configure(text="")
except:
self.lbl_error.configure(text="ERROR: Cannot get info from device")
self.after(1000, lambda: self.updateData())
for i in range(8):
self.table.insert(parent='', index='end',
values=('INPUT ' + str(i + 1), pulses[i])) #
self.after(1000, lambda: self.updateData())
I really don't have any idea of why is this happening, because i made so many changes on the app, and it wasn't working wrong after this new structure hahahaha
Thank u all :)

Related

How to raise the frame in multiple panned windows if user chooses option in one window that should be reflected in another panned window frame?

I am new to python need help in raising the frames in different panned window if user chooses option in another panned window frame, I will post the code please help me. I choosed combobox for my usecases whenever user chooses any of the usecase and click submit button. I want respective settings for those use cases to be as a frame in the container frame in SettingsUi panned Window frame. Please suggest me any solution.I tried raising frames by creating them as seperate class but facing issue and tried to create the frames with in that SettingUi by checking the combobox conditions and trying to give that function to the submit button in FmUi class.
import tkinter as tk
from tkinter import ttk
from tkinter.scrolledtext import ScrolledText
from tkinter import ttk, VERTICAL, HORIZONTAL, N, S, E, W
class UseCase1(tk.Frame):
def __init__(self,parent):
super().__init__(parent)
ttk.Label(self,text="UseCase1").pack()
# button = tk.Button(self, text="Go to the start page",
# command=lambda:show_frame("UseCase1")).pack()
self.pack()
class UseCase2(tk.Frame):
def __init__(self, parent):
# tk.Frame.__init__(self, parent)
super().__init__(parent)
ttk.Label(self,text="UseCase2").pack()
# label = tk.Label(self, text="This is page 1", font=controller.title_font)
# label.pack(side="top", fill="x", pady=10)
# button = tk.Button(self, text="Go to the start page")
# button.pack()
self.pack()
class UseCase3(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
button = tk.Button(self, text="UseCase3")
button.pack()
class FmUi:
def __init__(self, frame):
# Create a combobbox to select the Usecase level
self.frame = frame
# self.switchframe()
# Create a combobbox to select the Usecase level
values = ['UseCase1', 'UseCase2', 'Usecase3', 'Usecase4', 'Usecase5']
self.level = tk.StringVar()
ttk.Label(self.frame, text='Level:').grid(column=0, row=0, sticky=W)
self.combobox = ttk.Combobox(
self.frame,
textvariable=self.level,
width=25,
state='readonly',
values=values
)
self.combobox.current(0)
self.combobox.grid(column=1, row=0, sticky=(W, E))
self.combobox.bind('<<ComboboxSelected>>', self.on_select)
# # Create a text field to enter a message
# self.message = tk.StringVar()
# ttk.Label(self.frame, text='Message:').grid(column=0, row=1, sticky=W)
# ttk.Entry(self.frame, textvariable=self.message, width=25).grid(column=1, row=1, sticky=(W, E))
self.button = ttk.Button(self.frame, text='Submit',command=SettingsUi.switch_frame(self.combobox.get()))
self.button.grid(column=1, row=1, sticky=W)
# self.frame.grid_columnconfigure(0, weight=1)
# self.frame.grid_rowconfigure(0, weight=1)
def on_select(self, event):
global SummaryText
SummaryText = self.combobox.get()
class SettingsUi(tk.Frame,FmUi):
def __init__(self, frame, *args, **kwargs):
tk.Frame.__init__(self,frame,*args, **kwargs)
self.frame = frame
self._frame = None
self.switch_frame(UseCase1)
def switch_frame(self, frame_class):
new_frame = frame_class(self)
if self._frame is not None:
self._frame.destroy()
self._frame = new_frame
self._frame.pack()
# container = tk.Frame(self)
# container.pack(side = "top", fill = "both", expand = True)
# container.grid_rowconfigure(0, weight = 1)
# container.grid_columnconfigure(0, weight = 1)
class OutputUi:
def __init__(self, frame):
self.frame = frame
self.scrolled_text = ScrolledText(frame, state='disabled', height=12)
self.scrolled_text.grid(row=0, column=0,sticky=(N, S, W, E))
self.scrolled_text.configure(font='TkFixedFont')
self.frame.grid_columnconfigure(0, weight=1)
self.frame.grid_rowconfigure(0, weight=1)
class App:
def __init__(self, root):
self.root = root
root.title('Automation')
self.menubar =tk.Menu(self.root)
# Adding File Menu and commands
# file = Menu(menubar, tearoff = 0)
# menubar.add_cascade(label ='UseCase', menu = UseCase)
# file.add_command(label ='', command = None)
# file.add_command(label ='', command = None)
# file.add_command(label ='Save', command = None)
# file.add_separator()
# file.add_command(label ='Exit', command = root.destroy)
# Adding Edit Menu and commands
self.Help =tk.Menu(self.menubar, tearoff = 0 , font = ("", 10))
self.menubar.add_cascade(label ='Help ', menu =self.Help, font = ("", 10))
self.Help.add_command(label ='Hotline ', command = None,font = ("", 10))
self.Help.add_command(label ='Documentation', command = None,font = ("", 10))
# edit.add_command(label ='Paste', command = None)
# edit.add_command(label ='Select All', command = None)
# edit.add_separator()
# edit.add_command(label ='Find...', command = None)
# edit.add_command(label ='Find again', command = None)
# Adding Help Menu
self.About=tk.Menu(self.menubar, tearoff = 0,font = ("", 10))
self.menubar.add_cascade(label ='About ', menu = self.About,font = ("", 10))
self.About.add_command(label ='About GUI', command = None,font = ("", 10))
self.About.add_command(label ='Demo', command = None,font = ("", 10))
# help_.add_separator()
# help_.add_command(label ='About Tk', command = None)
# display Menu
root.config(menu = self.menubar)
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
# Create the panes and frames
vertical_pane = ttk.PanedWindow(self.root, orient=VERTICAL)
vertical_pane.grid(row=0, column=0, sticky="nsew")
horizontal_pane = ttk.PanedWindow(vertical_pane, orient=HORIZONTAL)
vertical_pane.add(horizontal_pane)
form_frame = ttk.Labelframe(horizontal_pane, text="Options")
form_frame.columnconfigure(1, weight=1)
horizontal_pane.add(form_frame, weight=1)
console_frame = ttk.Labelframe(horizontal_pane, text="Configuration")
console_frame.columnconfigure(0, weight=1)
console_frame.rowconfigure(0, weight=1)
horizontal_pane.add(console_frame, weight=1)
third_frame = ttk.Labelframe(vertical_pane, text="Console")
vertical_pane.add(third_frame, weight=1)
# GR_frame=ttk.Frame(console_frame)
# EP_frame=ttk.Frame(console_frame)
# Initialize all frames
self.form = FmUi(form_frame)
self.console = SettingsUi(console_frame)
self.third = OutputUi(third_frame)
def quit(self, *args):
self.root.destroy()
def main():
root = tk.Tk()
app = App(root)
app.root.mainloop()
if __name__ == '__main__':
main()
error I am getting
File ~\Documents\SubmissionFolder\untitled29082047.py:168 in
main()
File ~\Documents\SubmissionFolder\untitled29082047.py:163 in main
app = App(root)
File ~\Documents\SubmissionFolder\untitled29082047.py:154 in init
self.form = FmUi(form_frame)
File ~\Documents\SubmissionFolder\untitled29082047.py:62 in init
self.button = ttk.Button(self.frame, text='Submit',command=SettingsUi.switch_frame(self.combobox.get()))
TypeError: switch_frame() missing 1 required positional argument: 'frame_class'

How to get the values of all the OptionMenu widgets within a frame inside a canvas in Tkinter

I'm writing a minimalist image tagging app that will list out all the image files in a specific location alongside a dropdown menu to select the options for tagging the image. Once the images are tagged, I need to save the changes to a JSON file and I've got a button for that. How can we read all the options selected so that it can be written into a file?
Following is the code so far:
from tkinter import N, RIGHT, Button, OptionMenu, Scrollbar, StringVar, Tk, Canvas, Frame, Label
class App:
def __init__(self):
self.root = Tk()
self.tags = ['Apples', 'Oranges', 'Berries']
self.GetRows()
self.SaveButton()
self.root.mainloop()
def GetRows(self):
self.canvas = Canvas(self.root)
self.scroll_y = Scrollbar(self.root, orient="vertical", command=self.canvas.yview)
self.frame = Frame(self.canvas)
lst = [f"A01{str(i)}.JPG" for i in range(100)]
for idx, r in enumerate(lst):
filename = Label(self.frame, text=r)
filename.grid(row=idx+2, column=0, sticky=N)
label = StringVar()
drop = OptionMenu(self.frame, label, *self.tags)
drop.grid(row=idx+2, column=1)
# put the frame in the canvas
self.canvas.create_window(0, 0, anchor='nw', window=self.frame)
# make sure everything is displayed before configuring the scrollregion
self.canvas.update_idletasks()
self.canvas.configure(scrollregion=self.canvas.bbox('all'),
yscrollcommand=self.scroll_y.set)
self.canvas.pack(fill='both', expand=True, side='left')
self.scroll_y.pack(fill='y', side='right')
def SaveState(self):
pass
def SaveButton(self):
self.save_button = Button(self.root, text="Save Changes", padx=50, pady=10, command=self.SaveState)
self.save_button.pack(side=RIGHT)
if __name__ == '__main__':
App()
The SaveState method is what will be used to write the selections so far into a file.
Thanks in advance!
In order to make OptionMenu results available try modifying your code so that
all StringVars are accessible outside of GetRows.
def GetRows(self):
...
# Define label as a list
self.label = []
for idx, r in enumerate(lst):
filename = Label(self.frame, text=r)
filename.grid(row=idx+2, column=0, sticky=N)
label = StringVar()
drop = OptionMenu(self.frame, label, *self.tags)
drop.grid(row=idx+2, column=1)
# Save StringVar reference
self.label.append(label)
...
def SaveState(self):
self.data = dict()
# Retrieve results into dictionary
for i, a in enumerate(self.label):
self.data[f"A_{i}"] = a.get()
print(self.data)
Then use json.dump(self.data, a_file) to save it

Is it possible to grab input from the topview tkinter window and retrieve saved entry field value from within master tk window

The program is made up of classes and I am trying to use a tkinter topview from within a function so that when it's called it is able to retrieve the entryfield value to the master class
from tkinter import
from PIL import Image, ImageTk
Below is the driver code handling the transitioning from one class to another
class SeaofBTCapp(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
container = Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (
WelcomePage, Register_new_user): # ,PageThree,PageFour):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(WelcomePage)
# def show_frame(self, cont):
# frame = self.frames[cont]
# frame.tkraise()
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
frame.update()
frame.event_generate("<<show_frame>>")
def get_page(self, cont):
for page in self.frames.values():
if str(page.__class__.__name__) == cont:
return page
return None
class Register_new_user(object):
pass
Below is the entry point of the program and is the first page to be displayed
class WelcomePage(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
# self.bind("<<show_frame>>", self.main_prog)
def resize_image(event):
global photo
new_width = event.width
new_height = event.height
image = copy_of_image.resize((new_width, new_height))
photo = ImageTk.PhotoImage(image)
label.config(image=photo)
label.image = photo # avoid garbage collection
def pin_input():
top = Toplevel()
top.geometry("180x100")
top.title("toplevel")
l2 = Label(top, text="This is toplevel window")
global entry_1
global password
password = StringVar
entry_1 = None
def cleartxtfield():
global password
new = "3"
password.set(new)
# ############# Function to parse for only numerical input
def validate(input):
if input.isdigit():
return True
elif input == "":
return True
else:
return False
def enternumber(x):
global entry_1
setval = StringVar()
setval = str(x)
# print(setval)
entry_1.insert(END, setval)
entry_1 = Entry(top, textvariable=password, width=64, show='*')
entry_1.place(x=200, y=100)
entry_1.focus()
reg = top.register(validate)
entry_1.config(validate="key", validatecommand=(reg, '%P'))
def getcreds():
# check if four digit entered and is not empty
global passwd
passwd = password.get()
print(f"The Credentials are {passwd}")
def funcbackspace():
length = len(entry_1.get())
entry_1.delete(length - 1, 'end')
def killwindow():
# when the user quits it should clear all the data input fields filled in in the previous steps. and should display information that it is about to quit in a few seconds
command = top.destroy()
# Label(top,text="Goodbye\n (Closing in 2 seconds)")
top.after(2000, top.quit())
cancel = Button(top, width=8, height=3, text="Cancel", bg="red", fg="black", command=killwindow)
cancel.place(x=220, y=150)
backspace = Button(top, width=8, height=3, text="Backspace", bg="red", fg="black", command=funcbackspace)
backspace.place(x=500, y=150)
# ----number Buttons------
def enternumber(x):
global entry_1
setval = StringVar()
setval = str(x)
# print(setval)
entry_1.insert(END, setval)
btn_numbers = []
for i in range(10):
btn_numbers.append(
Button(top, width=8, height=3, text=str(i), bd=6, command=lambda x=i: enternumber(x)))
btn_text = 1
for i in range(0, 3):
for j in range(0, 3):
btn_numbers[btn_text].place(x=220 + j * 140, y=250 + i * 100)
btn_text += 1
btn_zero = Button(top, width=15, height=2, text='0', bd=5, command=lambda x=0: enternumber(x))
btn_zero.place(x=330, y=550)
clear = Button(top, text="Clear", bg="green", fg="white", width=8, height=3, command=cleartxtfield)
clear.place(x=220, y=550)
okbtn = Button(top, text="Enter", bg="green", fg="black", width=8, height=3, command=getcreds)
okbtn.place(x=500, y=550)
val = getcreds()
print("The value to be returned is %s" % val)
return val
password = pin_input()
print("Gotten password is %s" % password)
copy_of_image = Image.open("image.png")
photoimage = ImageTk.PhotoImage(copy_of_image)
label = Label(self, image=photoimage)
label.place(x=0, y=0, relwidth=1, relheight=1)
label.bind('<Configure>', resize_image)
top_left_frame = Frame(self, relief='groove', borderwidth=2)
top_left_frame.place(relx=1, rely=0.1, anchor=NE)
center_frame = Frame(self, relief='raised', borderwidth=2)
center_frame.place(relx=0.5, rely=0.75, anchor=CENTER)
Button(top_left_frame, text='REGISTER', bg='grey', width=14, height=1,
command=lambda: controller.show_frame(Register_new_user)).pack()
Button(center_frame, text='ENTER', fg='white', bg='green', width=13, height=2,
command=lambda: controller.show_frame(Register_new_user)).pack()
if __name__ == '__main__':
app = SeaofBTCapp()
app.title("Password return on topview window")
width = 1000
height = 700
screenwidth = app.winfo_screenwidth()
screenheight = app.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
app.geometry(alignstr)
# app.resizable(width=False, height=False)
app.resizable(width=True, height=True)
app.mainloop()
If I understand this correctly you want to enter a password in a dialog and then get the password from the dialog when you close it.
Have a look at Dialog Windows at effbot for a discussion about creating dialog windows.
Here is an example of how you can implement a simple dialog:
from tkinter import *
from tkinter import simpledialog
class MyDialog(simpledialog.Dialog):
def body(self, master):
'''create dialog body.
return widget that should have initial focus.
This method should be overridden, and is called
by the __init__ method.'''
Label(master, text='Value:').grid(row=0)
self.e1 = Entry(master)
self.e1.grid(row=0, column=1)
return self.e1 # initial focus
def apply(self):
'''process the data
This method is called automatically to process the data, *after*
the dialog is destroyed. By default, it does nothing.'''
value = self.e1.get()
self.result = value
def validate(self):
'''validate the data
This method is called automatically to validate the data before the
dialog is destroyed. By default, it always validates OK.'''
return 1 # override
def buttonbox(self):
'''add standard button box.
override if you do not want the standard buttons
'''
box = Frame(self)
w = Button(box, text="OK", width=10, command=self.ok, default='active')
w.pack(side='left', padx=5, pady=5)
w = Button(box, text="Cancel", width=10, command=self.cancel)
w.pack(side='left', padx=5, pady=5)
self.bind("<Return>", self.ok)
self.bind("<Escape>", self.cancel)
box.pack()
if __name__ == '__main__':
root = Tk()
root.geometry('200x100+800+50')
def do():
d = MyDialog(root)
print(d.result)
b = Button(root, text='Go!', width=10, command=do)
b.pack(expand=True)
Did that answer your question?

Change Entry widget value from other function

I am quite new in programming with tkinter , especially with classes. How can I make a button that runs function from the same class and changes entry widget. In my code i want to change entry1 whenever button1 is clicked and filepath function runs.
thank you for your help.
Class Example(Frame):
def __init__(self):
super().__init__()
self.initUI()
def filepath():
filename = fd.askopenfilename()
entry1.delete(0,END)
entry1.insert(0,filename)
def initUI(self):
self.master.title("EFEKTYWNOŚĆ APP")
self.pack(fill=BOTH, expand=True)
cd = (os.getcwd())
frame1 = Frame(self)
frame1.pack(side = LEFT)
lbl1 = Label(frame1,
text="...",
wraplength = 250 )
lbl1.pack(side=LEFT, padx=5, pady=5)
path = os.path.join(cd, 'ico', '...')
photo = PhotoImage(file = path)
cphoto = photo.subsample(4,4)
button1 = Button(frame1,
text='WYBIERZ PLIK',
image = cphoto,
compound = LEFT,
command = Example.filepath)
button1.image = cphoto
button1.pack(side=LEFT, fill = Y, padx=5, pady=5)
entry1 = Entry(frame1)
entry1.pack(side=LEFT, fill = Y, padx=5, pady=5)
There are some minor things needed to be fixed in your code. I have added a working sample with comments below.
from tkinter import *
from tkinter import filedialog as fd
import os
class Example(Frame):
def __init__(self, master,**kwargs): #have your Frame accept parameters like how a normal frame should
super().__init__(master,**kwargs)
self.master = master #set master as an attribute so you can access it later
self.initUI()
def filepath(self): #add self to make the method an instance method
filename = fd.askopenfilename()
self.entry1.delete(0, END) #use self when referring to an instance attribute
self.entry1.insert(0, filename)
def initUI(self):
self.master.title("EFEKTYWNOŚĆ APP")
self.pack(fill=BOTH, expand=True)
cd = (os.getcwd())
frame1 = Frame(self)
frame1.pack(side=LEFT)
lbl1 = Label(frame1,
text="...",
wraplength=250)
lbl1.pack(side=LEFT, padx=5, pady=5)
path = os.path.join(cd, 'ico', '...')
photo = PhotoImage(file=path)
cphoto = photo.subsample(4, 4)
button1 = Button(frame1,
text='WYBIERZ PLIK',
image=cphoto,
compound=LEFT,
command=self.filepath) #refer to instance methods by self.your_method
button1.pack(side=LEFT, fill=Y, padx=5, pady=5)
self.entry1 = Entry(frame1) #add self to make it an instance attribute
self.entry1.pack(side=LEFT, fill=Y, padx=5, pady=5) #you will then need to use self.entry1 within your class instance
root = Tk()
Example(root)
root.mainloop()

Using a conditional statement to link a button press

The idea is that if one presses one of the buttons the labeled text is inputted in the top left entry box. My initial plan was to use an if statement when the button is pressed and then insert the text according.
However, I am not sure what syntax to use that would allow me to make this one line conditional statement that recognizes the button being pressed. Is this actually possible or do I need to make a separate function?
from tkinter import *
from tkinter import ttk
class GUI():
def __init__(self, master):
self.master = master
master.resizable(True, True)
master.title('Conversion Calculator')
self.tabControl = ttk.Notebook(master)
self.tab1 = ttk.Frame(self.tabControl) # tab set up
self.tabControl.add(self.tab1, text='Builder')
self.tabControl.pack(expand=1, fill="both")
self.builder_entrybox = ttk.Entry(self.tab1, width=24) # entry box set up
self.builder_entrybox.grid(column=0, row=0)
self.builder_outputbox = ttk.Entry(self.tab1, width=24) # output box set up
self.builder_outputbox.grid(column=0, row=1)
self.builder_outputbox.config(state='NORMAL')
self.builder_outputbox.config(state='readonly')
self.CH3_Button = ttk.Button(self.tab1, text='CH3', command=self.builder) # CH3 button
self.CH3_Button.grid(column=1, row=0)
self.CH2_Button = ttk.Button(self.tab1, text='CH2', command=self.builder) # CH2 button
self.CH2_Button.grid(column=2, row=0)
self.OH_Button = ttk.Button(self.tab1, text='OH', command=self.builder) # OH button
self.OH_Button.grid(column=1, row=1)
self.O_Button = ttk.Button(self.tab1, text='O', command=self.builder) # O button
self.O_Button.grid(column=2, row=1)
self.H_Button = ttk.Button(self.tab1, text='H', command=self.builder) # H button
self.H_Button.grid(column=3, row=1)
self.COOH_Button = ttk.Button(self.tab1, text='COOH', command=self.builder) # COOH button
self.COOH_Button.grid(column=3, row=0)
class Logic(GUI):
def builder (self): # adding button text to entry box (tab1)
self.builder_entrybox.insert(0, 'CH3')
if __name__ == "__main__":
root = Tk()
test = Logic(root)
Yes, you would make a new function for every button:
class GUI():
def __init__(self, master):
# ...
self.CH3_Button = ttk.Button(self.tab1, text='CH3', command=self.CH3_builder) # CH3 button
self.CH3_Button.grid(column=1, row=0)
def CH3_builder(self):
self.builder_entrybox.insert('end', 'CH3')
Python can make functions on the fly, either with functools.partial (early binding) or lambda (late binding). Using that you could write the same thing like this:
from functools import partial
class GUI():
def __init__(self, master):
# ...
self.CH3_Button = ttk.Button(self.tab1, text='CH3', command=partial(self.builder_entrybox.insert, 'end', 'CH3')) # CH3 button
self.CH3_Button.grid(column=1, row=0)
But it would be better if you make a small subclass to handle all this for you, which makes your code very reusable and therefore neat:
from tkinter import ttk
import tkinter as tk
class Copa(ttk.Button):
"""A new type of Button that moves the text into a Entry when clicked"""
def __init__(self, master=None, **kwargs):
ttk.Button.__init__(self, master, command=self.builder, **kwargs)
def builder(self):
self.master.builder_entrybox.insert('end', self['text'])
class BuilderFrame(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.builder_entrybox = ttk.Entry(self, width=24) # entry box set up
self.builder_entrybox.grid(column=0, row=0)
self.builder_outputbox = ttk.Entry(self, width=24) # output box set up
self.builder_outputbox.grid(column=0, row=1)
self.builder_outputbox.config(state='NORMAL')
self.builder_outputbox.config(state='readonly')
self.CH3_Button = Copa(self, text='CH3') # CH3 button
self.CH3_Button.grid(column=1, row=0)
self.CH2_Button = Copa(self, text='CH2') # CH2 button
self.CH2_Button.grid(column=2, row=0)
self.OH_Button = Copa(self, text='OH') # OH button
self.OH_Button.grid(column=1, row=1)
self.O_Button = Copa(self, text='O') # O button
self.O_Button.grid(column=2, row=1)
self.H_Button = Copa(self, text='H') # H button
self.H_Button.grid(column=3, row=1)
self.COOH_Button = Copa(self, text='COOH') # COOH button
self.COOH_Button.grid(column=3, row=0)
class GUI():
def __init__(self, master):
self.master = master
master.resizable(True, True)
master.title('Conversion Calculator')
self.tabControl = ttk.Notebook(master)
self.tab1 = BuilderFrame(self.tabControl) # tab set up
self.tabControl.add(self.tab1, text='Builder')
self.tabControl.pack(expand=1, fill="both")
if __name__ == "__main__":
root = tk.Tk()
test = GUI(root)
root.mainloop()

Resources