Tkinter event error

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • TMS
    New Member
    • Sep 2006
    • 119

    #1

    Tkinter event error

    Only a few weeks of school left. This assignment and then a project to go (GASP).

    I'm writing a spreadsheet. I am required to have each 'cell' do 2 things: Evaluate if it is an equation, or if its a string just print it. Also, it is supposed to print the cell number on a different event reuqest.

    Right now, I'm trying to get it to evaluate an equation, and I'm real close. I'm getting errors in the onEvent() function. I know it has to do with a syntax issue and I'm hoping you can find it. Been looking at this since yesterday and I'm frustrated.

    I'm trying lambda functions, and perhaps that is where the problem is, or its just something else that I've overlooked. Here is what I have:

    Code:
    from Tkinter import *
    class spreadsheet(Frame):
    	"""
    	initialize columns and rows, default of 5
    	"""
    	def __init__(self, parent=None, numrow=5, numcol=5):
    		Frame.__init__(self, parent)
    		self.numrow = numrow
    		self.numcol = numcol
    		self.makeWidgets(numrow, numcol)
     
    	def onEvent(self, event, cell):
    		""" define events, evaluate and show cell
    		"""
    		if event.num == 1:
    			print cell  # this should actually replace what is in the cell without losing original data
    		if event.num == 3:
    			obj = dict[cell]   #error here, says cell is unscriptable.
    			data = obj.get()
    			if data.startwith('='):
    				eq = data.lstrip('=')
    				print data, eq
    				try:
    					result = eval(eq)
    					obj.delete(0, 'end')
    					obj.insert(0, str(result))
    				except:
    					pass  #nothing should crash the spreadsheet
     
    	def returnKey(event, cell):
    		pass
    	 
    	def makeWidgets(self, numrow, numcol):
    		"""
    		define labels for rows and columns, use entry widget, assign events, create dictionary of
    		cell:widget pair
    		"""
    		dict = {}
    		w = 20
    		h = 1
    		rowLabel = ["", 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
    		for row in range(numrow):
    			for col in range(numcol):
    				if col == 0:
    					# label rows
    					labels = Label(root, width = 3, text = rowLabel[row])
    					labels.grid(row=row, column=col, padx = 2, pady = 2)
    				elif row == 0:
    					# label columns
    					labels = Label(root, width=3, text = str(col-1))
    					labels.grid(row=row, column=col, padx = 2, pady =2)
    				else:
    					# use entry widget
    					entrys = Entry(root, width=w)
    					entrys.grid(row=row, column=col)
    					cell = "%s%s" %(rowLabel[col], row)
    					dict[cell] = entrys
    					# bind to left mouse click
    					entrys.bind('<Button-1>', lambda e, cell=cell: self.onEvent(e, cell))
    					# bind the object to a right mouse click
    					entrys.bind('<Button-3>', lambda e, cell=cell: self.onEvent(e, cell))
    					# bind the object to a return/enter press
    					entrys.bind('<Return>', lambda e, cell=cell: self.returnKey(e, cell))
    		# start curser in row a column 0
    		dict['a1'].focus()
    if __name__ == '__main__':
    	import sys
    	root = Tk()
    	root.title('S P R E A D S H E E T')
    	if len(sys.argv) != 3:
    		spreadsheet(root).grid()
    	else:
    		rows, cols = eval(sys.argv[1]), eval(sys.argv[2])
    		spreadsheet(root, rows, cols).grid()
    	root.mainloop()
    thank you ahead of time for your help. I look forward to learning this language AFTER the class is over, when I can go back to the stuff that I missed with the breakneck speeds we've been using since taking this class.

    TMS
  • bartonc
    Recognized Expert Expert
    • Sep 2006
    • 6478

    #2
    Very nice job!!! Your trouble was with your use of dict. That dictionary needed to be an instance variable too.
    Code:
    from Tkinter import *
    class spreadsheet(Frame):
        """
        initialize columns and rows, default of 5
        """
        def __init__(self, parent=None, numrow=5, numcol=5):
            Frame.__init__(self, parent)
            self.numrow = numrow
            self.numcol = numcol
    
            # Need to keep the entries dictionary in self
            self.entriesDict = {}    # an empty dictionary
            # Don't use the keyword "dict"; use somethingDict.
    
            self.makeWidgets(numrow, numcol)
    
        def onEvent(self, event, cell):
            """ define events, evaluate and show cell
            """
            if event.num == 1:
                print cell  # this should actually replace what is in the cell without losing original data
            if event.num == 3:
                obj = self.entriesDict[cell]   #error here, says cell is unscriptable.
                data = obj.get()
                if data.startswith('='):  # startswith() was startwith()
                    eq = data.lstrip('=')
                    print data, eq
                    try:
                        result = eval(eq)
                        obj.delete(0, 'end')
                        obj.insert(0, str(result))
                    except:
                        pass  #nothing should crash the spreadsheet
    
        def returnKey(self, event, cell):
            pass
    
        def makeWidgets(self, numrow, numcol):
            """
            define labels for rows and columns, use entry widget, assign events, create dictionary of
            cell:widget pair
            """
            dict = {}
            w = 20
            h = 1
            rowLabel = ["", 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
            for row in range(numrow):
                for col in range(numcol):
                    if col == 0:
                        # label rows
                        labels = Label(root, width = 3, text = rowLabel[row])
                        labels.grid(row=row, column=col, padx = 2, pady = 2)
                    elif row == 0:
                        # label columns
                        labels = Label(root, width=3, text = str(col-1))
                        labels.grid(row=row, column=col, padx = 2, pady =2)
                    else:
                        # use entry widget
                        entrys = Entry(root, width=w)
                        entrys.grid(row=row, column=col)
                        cell = "%s%s" %(rowLabel[col], row)
                        self.entriesDict[cell] = entrys
                        # bind to left mouse click
                        entrys.bind('<Button-1>', lambda e, cell=cell: self.onEvent(e, cell))
                        # bind the object to a right mouse click
                        entrys.bind('<Button-3>', lambda e, cell=cell: self.onEvent(e, cell))
                        # bind the object to a return/enter press
                        entrys.bind('<Return>', lambda e, cell=cell: self.returnKey(e, cell))
            # start curser in row a column 0
            self.entriesDict['a1'].focus()
    if __name__ == '__main__':
        import sys
        root = Tk()
        root.title('S P R E A D S H E E T')
        if len(sys.argv) != 3:
            spreadsheet(root).grid()
        else:
            rows, cols = eval(sys.argv[1]), eval(sys.argv[2])
            spreadsheet(root, rows, cols).grid()
        root.mainloop()

    Comment

    • TMS
      New Member
      • Sep 2006
      • 119

      #3
      OF COURSE... thank you :) I should have caught that.

      again... TYVM
      tms

      Comment

      • bartonc
        Recognized Expert Expert
        • Sep 2006
        • 6478

        #4
        Originally posted by TMS
        OF COURSE... thank you :) I should have caught that.

        again... TYVM
        tms
        You are welcome, very much. Any time!

        Comment

        Working...