Cable schedule form
- Jason Ron
- Aug 4, 2021
- 3 min read

Shown is a GUI I programed in python. This application simplifies electrical data
entry. Using python and tkinter you fill out the form shown and then press save, the data is then automatically transferred to a csv file for use in excel. This saves multiple entries to an existing csv file in same folder as the python or exe file. If csv file does not exist a new file will be created the first time you save.

Python resources:
super beginer: go to Udemy.com and take the Learn Python Programming Masterclass (get you set up)
Book used: Python GUI Programming with TKINTER www.packt.com
Code:
from datetime import datetime
import os
import csv
import tkinter as tk
from tkinter import ttk
# startcodinghere
class LabelInput(tk.Frame):
"""a widget containing a label and input together"""
def __init__(self, parent, label='', input_class=ttk.Entry, input_var=None, input_args=None, label_args=None,
**kwargs):
super().__init__(parent, **kwargs)
input_args = input_args or {}
label_args = label_args or {}
self.variable = input_var
if input_class in (ttk.Checkbutton, ttk.Button, ttk.Radiobutton):
input_args["text"] = label
input_args["variable"] = input_var
else:
self.label = ttk.Label(self, text=label, **label_args)
self.label.grid(row=0, column=0, sticky=(tk.W + tk.E))
input_args["textvariable"] = input_var
self.input = input_class(self, **input_args)
self.input.grid(row=1, column=0, sticky=(tk.W + tk.E))
self.columnconfigure(0, weight=1)
def grid(self, sticky=(tk.E + tk.W), **kwargs):
super().grid(sticky=sticky, **kwargs)
def get(self):
try:
if self.variable:
return self.variable.get()
elif type(self.input) == tk.Text:
return self.input.get('1.0', tk.END)
else:
return self.input.get()
except (typeError, tk.TclError):
# happens when numeric fields are empty
return ''
def set(self, value, *args, **kwargs):
if type(self.variable) == tk.BooleanVar:
self.variable.set(bool(value))
elif self.variable:
self.variable.set(value, *args, **kwargs)
elif type(self.input) in (ttk.Checkbutton, ttk.Radiobutton):
if value:
self.input.select()
else:
self.input.deselect()
elif type(self.input) == tk.Text:
self.input.delete('1.0', tk.END)
self.input.insert('1.0', value)
else: # input must be an Entry-type widget with no variable
self.input.delete(0, tk.END)
self.input.insert(0, value)
class DataRecordForm(tk.Frame):
"""the input form for widget"""
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
# a dict to keep track of input widgets
self.inputs = {}
# title and date
recordinfo = tk.LabelFrame(self, text="Record information")
self.inputs['Date'] = LabelInput(recordinfo, "Date", input_var=tk.StringVar())
self.inputs['Date'].grid(row=0, column=0)
self.inputs['Engineer'] = LabelInput(recordinfo, "Engineer", input_var=tk.StringVar())
self.inputs['Engineer'].grid(row=0, column=1)
recordinfo.grid(row=0, column=0, sticky=tk.W + tk.E)
# cable schedule info
cableschedule = tk.LabelFrame(self, text="Cable Schedule")
self.inputs['Circuit Num'] = LabelInput(cableschedule, "Circuit TAG", input_var=tk.StringVar())
self.inputs['Circuit Num'].grid(row=1, column=0)
self.inputs['Cable type'] = LabelInput(cableschedule, "Cable Type", input_class=ttk.Combobox,
input_var=tk.StringVar(), input_args={
"values": ["THHN", "THWN", "THWN-2", "TFFN", "RHN", "THN", "USE", "FIBER", "COAX", "ETHERNET"]})
self.inputs['Cable type'].grid(row=1, column=1)
self.inputs['Quantity'] = LabelInput(cableschedule, "Quantity", input_class=ttk.Spinbox, input_var=tk.IntVar(),
input_args={"from": 0, "to": 15, "increment": 1})
self.inputs['Quantity'].grid(row=1, column=2)
self.inputs['Siginal'] = LabelInput(cableschedule, "Siginal", input_class=ttk.Combobox,
input_var=tk.StringVar(), input_args={
"values": ["Service", "4-20mA", "24VDC", "Digital", "Control", "mV", "COM"]})
self.inputs['Siginal'].grid(row=1, column=3)
self.inputs['Voltage'] = LabelInput(cableschedule, "Voltage", input_class=ttk.Combobox,
input_var=tk.StringVar(),
input_args={"values": ["480V", "208V", "120V", "24VDC", "NA"]})
self.inputs['Voltage'].grid(row=1, column=4)
self.inputs['No Conductors'] = LabelInput(cableschedule, "No Conductors", input_class=ttk.Combobox,
input_var=tk.StringVar(), input_args={
"values": ["1/C", "2/C", "2/C /G", "3/C", "3/C /G", "4/C", "5/C", "6/C", "7/C", "8/C", "12/C", "16/C",
"TSHPR"]})
self.inputs['No Conductors'].grid(row=1, column=5)
self.inputs['Size AWG or KCMIL'] = LabelInput(cableschedule, "Size AWG or KCMIL", input_class=ttk.Combobox,
input_var=tk.StringVar(), input_args={
"values": ["18", "16", "14", "12", "10", "8", "6", "4", "3", "2", "1", "1/0", "2/0", "3/0", "4/0",
"250", "300", "350", "400", "500", "600", "700", "750"]})
self.inputs['Size AWG or KCMIL'].grid(row=1, column=6)
self.inputs['From Tag No'] = LabelInput(cableschedule, "From Tag No", input_var=tk.StringVar())
self.inputs['From Tag No'].grid(row=1, column=7)
self.inputs['From Tag Description'] = LabelInput(cableschedule, "From Tag Description",
input_var=tk.StringVar())
self.inputs['From Tag Description'].grid(row=1, column=8)
self.inputs['To Tag No'] = LabelInput(cableschedule, "To Tag No", input_var=tk.StringVar())
self.inputs['To Tag No'].grid(row=1, column=9)
self.inputs['To Tag Description'] = LabelInput(cableschedule, "To Tag Description", input_var=tk.StringVar())
self.inputs['To Tag Description'].grid(row=1, column=10)
self.inputs['Estimated Length'] = LabelInput(cableschedule, "Estimated Length", input_var=tk.StringVar())
self.inputs['Estimated Length'].grid(row=3, column=0)
self.inputs['From Drawing Number'] = LabelInput(cableschedule, "From Drawing Number", input_var=tk.StringVar())
self.inputs['From Drawing Number'].grid(row=3, column=1)
self.inputs['To Drawing Number'] = LabelInput(cableschedule, "To Drawing Number", input_var=tk.StringVar())
self.inputs['To Drawing Number'].grid(row=3, column=1)
self.inputs['Route'] = LabelInput(cableschedule, "Route", input_var=tk.StringVar())
self.inputs['Route'].grid(row=3, column=1)
cableschedule.grid(row=4, column=0, sticky=tk.W + tk.E)
# notes section
self.inputs['Notes'] = LabelInput(self, "Notes", input_class=tk.Text, input_args={"width": 150, "height": 5})
self.inputs['Notes'].grid(sticky="w", row=5, column=0)
self.reset()
def get(self):
data = {}
for key, widget in self.inputs.items():
data[key] = widget.get()
return data
def reset(self):
for widget in self.inputs.values():
widget.set('')
class Application(tk.Tk):
"application root window"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.title("My project")
self.resizable(width=False, height=False)
ttk.Label(self, text="My project cable sched", font=("TkdefaultFont", 16)).grid(row=0)
self.recordform = DataRecordForm(self)
self.recordform.grid(row=1, padx=10)
self.savebutton = ttk.Button(self, text="Save", command=self.on_save)
self.savebutton.grid(sticky=tk.E, row=10, padx=10)
# statusbar
self.status = tk.StringVar()
self.statusbar = ttk.Label(self, textvariable=self.status)
self.statusbar.grid(sticky=(tk.W + tk.E), row=11, padx=10)
self.records_saved = 0
self.records_saved += 1
self.status.set("{} records saved this session".format(self.records_saved))
def on_save(self):
datestring = datetime.today().strftime("%Y-%m-%d")
filename = "Cable_schedule_form_{}.csv".format(datestring)
newfile = not os.path.exists(filename)
data = self.recordform.get()
self.records_saved += 1
self.status.set("{} records saved this session".format(self.records_saved))
with open(filename, 'a') as fh:
csvwriter = csv.DictWriter(fh, fieldnames=data.keys())
if newfile:
csvwriter.writeheader()
csvwriter.writerow(data)
self.records_saved += 1
self.status.set("{} records saved this session".format(self.records_saved))
self.recordform.reset()
if __name__ == "__main__":
app = Application()
app.mainloop()
Comentarios