GUI Execute Commands
Here’s my Python – TKinter App that takes a set of Shell Commands from a .json file and displays them for individual execution when a button is clicked. Write these frequently used commands once and let the GUI program remember their syntax.
Keep 3 files in the same directory:
- guiExecuteCommands.py The TKInter Program
- config.json The Configuration Data
- cmds.json The Initial Command Set
Contents
- The TKInter Program File – guiExecuteCommands.py
- The Configuration Data File – config.json
- The Initial Command Set – cmds.json
- A Screenshot of the TKInter Program
- A run log of the program
The TKInter Program File – guiExecuteCommands.py
Here is the guiExecuteCommands.py file.
#!/usr/bin/python # -*- coding: utf-8 -*- # guiExecuteCommands.py import sys, os, time, subprocess, json, atexit # if not('.' in sys.path): sys.path.append('.') # from MyCommands import cmds import Tkinter, tkFileDialog class Theapp(Tkinter.Tk): def __init__(self,parent): # joe's init with open('config.json') as data_file: cfg_data = json.load(data_file) self.cfg_data = cfg_data with open(cfg_data[0]['commandsf']) as data_file: cmds = json.load(data_file) self.cmds = cmds atexit.register(self.on_exit) # http://stackoverflow.com/a/28664350/601770 # /joe's init Tkinter.Tk.__init__(self,parent) self.parent = parent self.initialize() def on_exit(self): ''' http://stackoverflow.com/a/28664350/601770 save the state that has been changed ''' self.cfg_data[0]['workingd'] = self.cwd.get() print "self.cwd.get(): %s"%(self.cwd.get()) print "self.cfg_data: %s"%(self.cfg_data) with open('config.json', 'w') as f: json.dump(self.cfg_data, f) def execute_cmd(self, rnum): ''' C:\1d\PythonPjs\subprocessPjs\executeCommandsPj\executeCommands\executeCommands.py ''' commandstring = self.cmd_entries[rnum].get() cwdpath = self.cwd.get() outstr = subprocess.check_call(commandstring, cwd=cwdpath, shell=True) # Convenience Function print outstr ## http://stackoverflow.com/a/16777523/601770 def bclick(self, rnum): def click(): self.execute_cmd(rnum) return click def browse2cwd(self): """ http://stackoverflow.com/questions/11295917/how-to-select-a-directory-and-store-the-location-using-tkinter-in-python http://tkinter.unpythonic.net/wiki/tkFileDialog find "def askdirectory(self):" """ tkFileDiaOpt4Dir = {} tkFileDiaOpt4Dir['initialdir'] = self.cwd.get() tkFileDiaOpt4Dir['mustexist'] = False tkFileDiaOpt4Dir['parent'] = self tkFileDiaOpt4Dir['title'] = 'Browse to set CWD.' self.cwd.set( tkFileDialog.askdirectory(**tkFileDiaOpt4Dir) ) print "browse2cwd: self.cwd.get(): %s"%(self.cwd.get()) def initialize(self): self.cwd = Tkinter.StringVar() self.cwd.set(self.cfg_data[0]['workingd']) self.grid() # make this be a grid ### add the gui elements in here ## browse to working directory label = Tkinter.Label(self, text="Working Directory", fg="white",bg="blue") label.grid(column=0,row=0,columnspan=3,sticky='W') self.cwd_entry = Tkinter.Entry(self, width=80, textvariable=self.cwd) self.cwd_entry.grid(column=0,row=1,columnspan=2, sticky='W') # http://effbot.org/tkinterbook/entry.htm b = Tkinter.Button(self,text=u"Browse", command=self.browse2cwd) b.grid(column=2,row=1) toprowscount = 2 ## command row elements len == len(MyCommands.cmds) self.buttons = [] self.cmd_entries = [] for rnum, cmd in enumerate(self.cmds): label = Tkinter.Label(self, anchor="w",text=cmd['label'], fg="white",bg="blue") label.grid(column=0,row=rnum+toprowscount,sticky='EW') self.cmd_entries.append( Tkinter.Entry(self, width=60) ) self.cmd_entries[-1].grid(column=1,row=rnum+toprowscount,sticky='EW'); self.cmd_entries[-1].insert(0, (cmd['cmd']+' '+ cmd['args'])) b = Tkinter.Button(self,text=u"Ex%s"%(rnum), command=self.bclick(rnum)) b.grid(column=2,row=rnum+toprowscount) self.buttons.append(b) ## Finish up self.grid_columnconfigure(0,weight=1) # make resizable self.resizable(True,False) # make resizable ONLY HORIZONTALLY if __name__ == "__main__": app = Theapp(None) app.title('Gui Execute Comands') app.mainloop()
The Configuration Data File – config.json
Here is the config.json file.
[{ "programd": "C:\\1d\\PythonPjs\\GUIpjs\\guiExecuteCommandPj\\guiExecuteCommand", "commandsf": "C:\\1d\\PythonPjs\\GUIpjs\\guiExecuteCommandPj\\guiExecuteCommand\\cmds.json", "configd": "C:\\1d\\PythonPjs\\GUIpjs\\guiExecuteCommandPj\\guiExecuteCommand", "workingd": "C:/1d/CrossPlatformPjs/CordovaPjs/cordovaAngular00Pj/cordovaAngular00" }]
The Initial Command Set – cmds.json
Here is the (INITIAL) cmds.json file
[ {"cmd": "cordova", "args": "run android", "label": "android build 4 device"}, {"cmd": "cordova", "args": "emulate android", "label": "android build 4 emulation"}, {"cmd": "dir", "args": "*", "label": "dir of working dir"} ]
A Screenshot of the TKInter Program
Here is a screenshot of the program.
A run log of the program
Here is a run log.
Note: if the user changed the working directory, on exit the new working directory will be saved in the config.json file.
C:\1bat\guiExecuteCommands>guiExecuteCommands.py browse2cwd: self.cwd.get(): C:/1d/CrossPlatformPjs/Building Single Page Web Apps with AngularJS PJ Volume in drive C is Windows Volume Serial Number is F2FB-4810 Directory of C:\1d\CrossPlatformPjs\Building Single Page Web Apps with AngularJS PJ 12/23/2015 09:58 AM <DIR> . 12/23/2015 09:58 AM <DIR> .. 12/23/2015 11:11 AM <DIR> zetc 0 File(s) 0 bytes 3 Dir(s) 900,352,217,088 bytes free 0 self.cwd.get(): C:/1d/CrossPlatformPjs/Building Single Page Web Apps with AngularJS PJ self.cfg_data: [{u'programd': u'C:\\1d\\PythonPjs\\GUIpjs\\guiExecuteCommandPj\\guiExecuteCommand', u'commandsf': u'C:\\1d\\PythonPjs\\GUIpjs\\guiExecuteCommandPj\\guiExecuteCommand\\cmds.json', u'configd': u'C:\\1d\\PythonPjs\\GUIpjs\\guiExecuteCommandPj\\guiExecuteCommand', u'workingd': u'C:/1d/CrossPlatformPjs/Building Single Page Web Apps with AngularJS PJ'}] C:\1bat\guiExecuteCommands>