3 Replies - 2167 Views - Last Post: 07 December 2009 - 04:28 AM Rate Topic: -----

#1 chemicalfan  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 88
  • Joined: 16-October 09

New Tkinter front-end for existing program

Post icon  Posted 24 November 2009 - 10:04 AM

Hi all!

Yes, my first post on this forum, and I come to you as an inexperienced Python coder. Brief background on myself - I'm a hobby programmer, learnt GW & QBASIC back in the day, tried early VB, then kinda left it. Decided to get back into hobby programming, looked at all the languages available, and chose Python. Got a good book, been reading it for the last year on and off, a lot of it makes a lot of sense (especially as my OO experience was zero).

Anyway, onto the issue I've got now. I'm writing a utility program for work, which will take a CSV file in, re-arrange it, and write a new one out. This is currently done by an Excel macro, which is a bit naff as Excel has a funny habit of applying it's own "style" to the file. I've already written a working program that does it from the CLI (well, 2 actually - one OO-based, and one not). My issue is, that it needs a GUI really, as I won't be the one running it in real life. So I've opted for Tkinter, as it's included with Python, so only one install required on the destination machines. Anyway, the code for the program is here:
import csv, sys, datetime

__metaclass__ = type

def arranger(a):
	b = []
	criteria = (15,1,0,1,3,4,10,9,7,5,0,0,6,14)
	for i in criteria:
		b.append(a[i])
	return b
	
class Fileobject(list):
	def reader(self,x):
		self.filename = open(sys.argv[1],'r')
		self.readeratt = csv.reader(self.filename)
		for row in self.readeratt:
			rowaslist = list(row)
			x.outputrow = arranger(rowaslist)
			print x.outputrow
			x.writer()
			
	def writer(self):
		self.filename = open(self.outputfilename,'a')
		writeratt = csv.writer(self.filename)
		writeratt.writerow(self.outputrow)
		self.filename.close()
			
outputnamedate = datetime.date(2009,10,14)
inputfile = Fileobject()
outputfile = Fileobject()
outputfile.outputfilename = 'Supplier Import File ' + str(outputnamedate.today()) + '.csv'
inputfile.reader(outputfile)
print outputfile.outputrow
outputfile.writer()
try: 
	inputfile.readeratt.next()
except StopIteration:
	print "Re-formatting successful"
	inputfile.filename.close()
	sys.exit()


It's not ideal at present, as I need to include more exception handling (as it stands, if someone tries to import a non-CSV file, it'll crash in an ugly Python way. Well, I quite like it actually :rolleyes: ). I've got the Tkinter part started, based on a simple tutorial - it's going to have 3 buttons: a load, a re-format, and a quit button. My big question, is how do I link the 2? So, when the user clicks the "re-format" button, it executes the program I've already written? Is it something to do with the 'mainloop()' part of the Tkinter program?

Is This A Good Question/Topic? 0
  • +

Replies To: New Tkinter front-end for existing program

#2 sempron644  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 19
  • Joined: 23-November 09

Re: New Tkinter front-end for existing program

Posted 27 November 2009 - 05:49 PM

View Postchemicalfan, on 24 Nov, 2009 - 09:04 AM, said:

Hi all!

Yes, my first post on this forum, and I come to you as an inexperienced Python coder. Brief background on myself - I'm a hobby programmer, learnt GW & QBASIC back in the day, tried early VB, then kinda left it. Decided to get back into hobby programming, looked at all the languages available, and chose Python. Got a good book, been reading it for the last year on and off, a lot of it makes a lot of sense (especially as my OO experience was zero).

Anyway, onto the issue I've got now. I'm writing a utility program for work, which will take a CSV file in, re-arrange it, and write a new one out. This is currently done by an Excel macro, which is a bit naff as Excel has a funny habit of applying it's own "style" to the file. I've already written a working program that does it from the CLI (well, 2 actually - one OO-based, and one not). My issue is, that it needs a GUI really, as I won't be the one running it in real life. So I've opted for Tkinter, as it's included with Python, so only one install required on the destination machines. Anyway, the code for the program is here:
import csv, sys, datetime

__metaclass__ = type

def arranger(a):
	b = []
	criteria = (15,1,0,1,3,4,10,9,7,5,0,0,6,14)
	for i in criteria:
		b.append(a[i])
	return b
	
class Fileobject(list):
	def reader(self,x):
		self.filename = open(sys.argv[1],'r')
		self.readeratt = csv.reader(self.filename)
		for row in self.readeratt:
			rowaslist = list(row)
			x.outputrow = arranger(rowaslist)
			print x.outputrow
			x.writer()
			
	def writer(self):
		self.filename = open(self.outputfilename,'a')
		writeratt = csv.writer(self.filename)
		writeratt.writerow(self.outputrow)
		self.filename.close()
			
outputnamedate = datetime.date(2009,10,14)
inputfile = Fileobject()
outputfile = Fileobject()
outputfile.outputfilename = 'Supplier Import File ' + str(outputnamedate.today()) + '.csv'
inputfile.reader(outputfile)
print outputfile.outputrow
outputfile.writer()
try: 
	inputfile.readeratt.next()
except StopIteration:
	print "Re-formatting successful"
	inputfile.filename.close()
	sys.exit()


It's not ideal at present, as I need to include more exception handling (as it stands, if someone tries to import a non-CSV file, it'll crash in an ugly Python way. Well, I quite like it actually :rolleyes: ). I've got the Tkinter part started, based on a simple tutorial - it's going to have 3 buttons: a load, a re-format, and a quit button. My big question, is how do I link the 2? So, when the user clicks the "re-format" button, it executes the program I've already written? Is it something to do with the 'mainloop()' part of the Tkinter program?


Hey, hows it going?
Well, looking over your code...
I think this syntax is invalid => b.append(a[i])
you might want to use the sort method, or the 'sorted' builtin function

onto the class declaration, I'm not sure what your opening with 'open(sys.argv[1],'r')'
seems troublesome to me to call a function inside a class, but it might work...
I seem to have more success calling the function outside of the class after collecting the needed input

you'll need to find a way to reset the data for the re-format button to have something to work with
perhaps re-loading it will work...
Was This Post Helpful? 1
  • +
  • -

#3 chemicalfan  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 88
  • Joined: 16-October 09

Re: New Tkinter front-end for existing program

Posted 30 November 2009 - 05:58 AM

View Postsempron644, on 27 Nov, 2009 - 04:49 PM, said:

Hey, hows it going?
Well, looking over your code...
I think this syntax is invalid => b.append(a[i])
you might want to use the sort method, or the 'sorted' builtin function

onto the class declaration, I'm not sure what your opening with 'open(sys.argv[1],'r')'
seems troublesome to me to call a function inside a class, but it might work...
I seem to have more success calling the function outside of the class after collecting the needed input

you'll need to find a way to reset the data for the re-format button to have something to work with
perhaps re-loading it will work...


Hi there, thanks for your reply - I think you've misunderstood my question though! The code I posted is fully functional, it just doesn't have a GUI at present. The user has to enter the filename when invoking the interpreter, and the open(sys.argv) call picks this up. I've attempted to code the GUI onto it, and it's not quite as "modular" as I would have liked (in other words, I've ended up cutting and pasting my current code into new methods/classes of the Tkinter code. Anyway, the program now falls over with an "AttributeError: tkfilename" when hitting the re-format button, even after clicking the "Load File" button first, and selecting the appropriate file. I fear this might be a global variable/local variable issue. The new code is here - any ideas what the issue is?:

import Tkinter, Tkconstants, tkFileDialog, sys, csv, datetime

__metaclass__ = type

def arranger(a):
	b = []
	criteria = (15,1,0,1,3,4,10,9,7,5,0,0,6,14)
	for i in criteria:
		b.append(a[i])
	return b
	
class Fileobject(list):
	def reader(self,x,gui):
		self.filename = open(gui.tkfilename,'r')
		self.readeratt = csv.reader(self.filename)
		for row in self.readeratt:
			rowaslist = list(row)
			x.outputrow = arranger(rowaslist)
			print x.outputrow
			x.writer()
			
	def writer(self):
		self.filename = open(self.outputfilename,'a')
		writeratt = csv.writer(self.filename)
		writeratt.writerow(self.outputrow)
		self.filename.close()

class TkFileDialogExample(Tkinter.Frame):

	def __init__(self, root):

		Tkinter.Frame.__init__(self, root)

		# options for buttons
		button_opt = {'fill': Tkconstants.BOTH, 'padx': 5, 'pady': 5}

		# define buttons
		Tkinter.Button(self, text='Load File', command=self.askopenfilename).pack(**button_opt)
		Tkinter.Button(self, text='Re-format', command=self.mainroutine).pack(**button_opt)
		Tkinter.Button(self, text='Quit', command=sys.exit).pack(**button_opt)   

		# defining options for opening or saving a file
		self.file_opt = options = {}
		options['defaultextension'] = '' # couldn't figure out how this works
		options['filetypes'] = [('CSV files', '.csv'), ('all files', '.*')]
		options['initialdir'] = 'C:\\'
		options['initialfile'] = ''
		options['parent'] = root
		options['title'] = 'Supplier reformatter'

	def askopenfilename(self):

		"""Returns an opened file in read mode.
		This time the dialog just returns a filename and the file is opened by your own code.
		"""

		# get filename
		self.tkfilename = tkFileDialog.askopenfilename(**self.file_opt)
		print self.tkfilename

		# open file on your own
		#if filename:
		#  return open(filename, 'r')

	def mainroutine(self):

		outputnamedate = datetime.date(2009,10,14)
		outputfile.outputfilename = 'Supplier Import File ' + str(outputnamedate.today()) + '.csv'
		inputfile.reader(outputfile,root)
		print outputfile.outputrow
		outputfile.writer()
		try: 
			inputfile.readeratt.next()
		except StopIteration:
			print "Re-formatting successful"
			inputfile.filename.close()
			outputfile.filename.close()
			sys.exit()

if __name__=='__main__':
	root = Tkinter.Tk()
	TkFileDialogExample(root).pack()
	inputfile = Fileobject()
	outputfile = Fileobject()
	root.mainloop()

This post has been edited by chemicalfan: 30 November 2009 - 05:59 AM

Was This Post Helpful? 0
  • +
  • -

#4 chemicalfan  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 88
  • Joined: 16-October 09

Re: New Tkinter front-end for existing program

Posted 07 December 2009 - 04:28 AM

*bump*

Really could do with a hand on this one guys, the system is now live and I can't deploy my utility yet!
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1