3
\$\begingroup\$

I had a read about classes, def, self, master, *args, **kwargs, __init__ and roots. Still trying to get my head around the whole thing.

I am struggling to structure my current code into classes and defs.

Here is my current code (below). It works perfectly fine, but I need to re-code it, re-structure it with classes, as I have been given a feedback from @BryanOakley to structure it with classes:

from tkinter import *
from tkinter.ttk import *
import glob
import os
from PIL import Image, ImageTk, ImageGrab
import tkinter as tk
import pyautogui
import datetime
import time
from pathlib import Path
#date & time
now = datetime.datetime.now()
root = tk.Tk()
root.title("SIGN OFF")
root.minsize(840, 400)
root.tk.call('wm', 'iconphoto', root._w, tk.PhotoImage(file='C:/Users/label/Desktop/Sign off project/tick.ico'))
# Frames
left_frame = tk.Frame()
right_frame = tk.Frame()
left_frame.pack(side="left", fill="both", expand=True)
right_frame.pack(side="right", fill="both", expand=True)
# Create a Tkinter variable
tkvar = tk.StringVar(root)
# Directory
directory = "C:/Users/label/Desktop/Sign off Project/sign off img"
choices = glob.glob(os.path.join(directory, "*.jpg"))
tkvar.set('...To Sign Off...') # set the default option
# On change dropdown callback.
def change_dropdown(*args):
 """ Updates label2 image. """
 imgpath = tkvar.get()
 img = Image.open(imgpath)
 img = img.resize((529,361))
 photo = ImageTk.PhotoImage(img)
 label2.image = photo
 label2.configure(image=photo)
p = None
def func(value):
 global p
 p = Path(value)
 print('req:', p)
#Seperating widgets
choose_label = tk.Label(left_frame, text="Choose your sign off here:")
popupMenu = tk.OptionMenu(left_frame, tkvar, *choices,command = func)
display_label = label2 = tk.Label(left_frame, image=None)
open_button = tk.Button(left_frame, text="Open", command=change_dropdown)
choose_label.grid(row=1, column=1)
popupMenu.grid(row=2, column=1)
display_label.grid(row=3, column=1)
open_button.grid(row=4, column=1)
def user():
 tk.Label(right_frame, text= "User: ", font = 'Helvetica 18 bold').grid(column = 1, row = 0, sticky = W)
 user_input = os.getlogin()
 tk.Label(right_frame, text = user_input, font='Helvetica 18 bold').grid(column = 1, row = 0, sticky = N)
user()
def var_states():
 text_file = open("logfile.txt", "a")
 text_file.write("TIME: %s, USER: %s, One %d, Two %d, Three %d, Four %d, Five %d, Six %d, Seven %d, Eight %d, Nine %d, Ten %d, Eleven %d, Twelve %d, Func %s\n" % (now,os.getlogin(), var1.get(), var2.get(), var3.get(), var4.get(), var5.get(), var6.get(), var7.get(), var8.get(), var9.get(), var10.get(), var11.get(), var12.get(), p))
 text_file.close()
#checkboxes
var1 = IntVar()
var2 = IntVar()
var3 = IntVar()
var4 = IntVar()
var5 = IntVar()
var6 = IntVar()
var7 = IntVar()
var8 = IntVar()
var9 = IntVar()
var10 = IntVar()
var11 = IntVar()
var12 = IntVar()
tk.Checkbutton(right_frame, text="Ingredients present in full (any allergens in bold with allergen warning if necessary)", variable=var1).grid(column = 1, row = 1, sticky = W)
tk.Checkbutton(right_frame, text="May Contain Statement.", variable=var2).grid(column = 1, row = 2, sticky = W)
tk.Checkbutton(right_frame, text="Cocoa Content (%).", variable=var3).grid(column = 1, row = 3, sticky = W)
tk.Checkbutton(right_frame, text="Vegetable fat in addition to Cocoa butter", variable=var4).grid(column = 1, row = 4, sticky = W)
tk.Checkbutton(right_frame, text="Instructions for Use.", variable=var5).grid(column = 1, row = 5, sticky = W)
tk.Checkbutton(right_frame, text="Additional warning statements (pitt/stone, hyperactivity etc)", variable=var6).grid(column = 1, row = 5, sticky = W)
tk.Checkbutton(right_frame, text="Nutritional Information Visible", variable=var7).grid(column = 1, row = 7, sticky = W)
tk.Checkbutton(right_frame, text="Storage Conditions", variable=var8).grid(column = 1, row = 8, sticky = W)
tk.Checkbutton(right_frame, text="Best Before & Batch Information", variable=var9).grid(column = 1, row = 9, sticky = W)
tk.Checkbutton(right_frame, text="Net Weight & Correct Font Size.", variable=var10).grid(column = 1, row = 10, sticky = W)
tk.Checkbutton(right_frame, text="Barcode - Inner", variable=var11).grid(column = 1, row = 11, sticky = W)
tk.Checkbutton(right_frame, text="Address & contact details correct", variable=var12).grid(column = 1, row = 12, sticky = W)
def save():
 var_states()
tk.Button(right_frame, text = "Save", command = save).grid(column = 1, row = 13, sticky = W)
root.mainloop()

What needs to be put into classes and what doesn't? I was thinking of having a left_frame and right_frame as two separate classes, or is that not needed?

UPDATE

Here is where I got to.. Am I heading in the right direction?

from tkinter import *
from tkinter import ttk
import glob
import os
from PIL import Image, ImageTk, ImageGrab
import tkinter as tk
import pyautogui
import datetime
import time
from pathlib import Path
class App:
 def __init__(self, master):
 #frames
 left_frame = Frame(master)
 right_frame = Frame(master)
 left_frame.pack(side="left", fill="both", expand=True)
 right_frame.pack(side="right", fill="both", expand=True)
 # Create a Tkinter variable
 App.tkvar = StringVar()
 # Directory
 directory = "C:/Users/label/Desktop/Sign off Project/sign off img"
 choices = glob.glob(os.path.join(directory, "*.jpg"))
 App.tkvar.set('...To Sign Off...') # set the default option
 # On change dropdown callback.
 def change_dropdown(*args):
 """ Updates label2 image. """
 imgpath = App.tkvar.get()
 img = Image.open(imgpath)
 img = img.resize((529,361))
 photo = ImageTk.PhotoImage(img)
 label2.image = photo
 label2.configure(image=photo)
 #Seperating widgets
 self.choose_label = Label(left_frame, text="Choose your sign off here:")
 self.popupMenu = OptionMenu(left_frame, App.tkvar, *choices)
 self.display_label = label2 = Label(left_frame, image=None)
 self.open_button = Button(left_frame, text="Open", command=change_dropdown)
 self.choose_label.grid(row=1, column=1)
 self.popupMenu.grid(row=2, column=1)
 self.display_label.grid(row=3, column=1)
 self.open_button.grid(row=4, column=1)
root = Tk()
root.minsize(840, 400)
app = App(root)
root.mainloop()
Reinderien
70.9k5 gold badges76 silver badges256 bronze badges
asked Sep 23, 2019 at 11:24
\$\endgroup\$
1
  • \$\begingroup\$ The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles. \$\endgroup\$ Commented Sep 23, 2019 at 14:32

1 Answer 1

3
\$\begingroup\$

Import sanity

These three:

from tkinter import *
from tkinter.ttk import *
import tkinter as tk

are not all needed at the same time. The first is the messiest - it simply floods your namespace with all tk symbols. The second is similarly messy. You're better off with:

import tkinter as tk
import tkinter.ttk as ttk

Path handling

Especially since you're in Windows, you should rethink your handling of paths. This:

directory = "C:/Users/label/Desktop/Sign off Project/sign off img"
choices = glob.glob(os.path.join(directory, "*.jpg"))

has a few issues. You should probably be using a relative path, first of all. Using an absolute path in a situation like this creates more complicated and fragile code.

Also, consider using the stuff from pathlib to simplify and clean up your filename operations.

My guess is that you'll end up with something like:

from pathlib import Path
choices = Path('sign off img').glob('*.jpg')

Args

def change_dropdown(*args):

The documentation does not mention any args to the callback - so simply delete *args.

Global code

root = Tk()
root.minsize(840, 400)
app = App(root)
root.mainloop()

Put this in a main function:

def main():
 root = Tk()
 root.minsize(840, 400)
 app = App(root)
 root.mainloop()
if __name__ == '__main__':
 main()
answered Sep 23, 2019 at 13:59
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.