By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,319 Members | 2,115 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,319 IT Pros & Developers. It's quick & easy.

Tkinter cell has 2 strings

TMS
100+
P: 119
This spreadsheet is almost done, but there is some functionality that is driving me nuts.

For instance: a cell, for instance 'a0' is to have 'a0' as a string, but if something is entered like '4+5', that is also there. So, at any time, one could see the cell number a0 or they could click on it and have the equation show as well. Right now, I can make it show the equation, and evaluate it, or it can also show the cell number. But I can't make it so if the user goes back to that cell after showing the cell number that the equation will show. It will always show the cell number based on the event, but it retains the part that was in there because I don't want to 'delete' it.

How do I save the equation without showing it all the time? I'm thinking it should be saved to the dictionary I already have, but alas I'm stumped. Any ideas?

Expand|Select|Wrap|Line Numbers
  1. from Tkinter import *
  2. class spreadsheet(Frame):
  3.     """
  4.     initialize columns and rows, default of 5
  5.     """
  6.     def __init__(self, parent=None, numrow=5, numcol=5):
  7.         Frame.__init__(self, parent)
  8.         self.numrow = numrow
  9.         self.numcol = numcol
  10.         self.entriesDict = {}    # an empty dictionary
  11.         self.makeWidgets(numrow, numcol)
  12.     def onEvent(self, event, cell):
  13.         """ define events, evaluate and show cell
  14.         """
  15.         if event.num == 1:
  16.             data = self.entriesDict[cell]
  17.             data.insert(0, str(cell))  
  18.         if event.num == 3:
  19.             obj = self.entriesDict[cell]   
  20.             data = obj.get()
  21.     def returnKey(self, event, cell):
  22.         """
  23.         define returnKey event
  24.         """
  25.         obj = self.entriesDict[cell]   
  26.         data = obj.get()
  27.         try:
  28.             result = eval(data)
  29.             obj.delete(0, 'end')
  30.             obj.insert(0, str(result))
  31.         except:
  32.             pass  #nothing should crash the spreadsheet
  33.  
  34.     def makeWidgets(self, numrow, numcol):
  35.         """
  36.         define labels for rows and columns, use entry widget, assign events, create dictionary of
  37.         cell:widget pair
  38.         """
  39.         dict = {}
  40.         w = 20
  41.         h = 1
  42.         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']
  43.         for row in range(numrow):
  44.             for col in range(numcol):
  45.                 if col == 0:
  46.                     # label rows
  47.                     labels = Label(root, width = 3, text = rowLabel[row])
  48.                     labels.grid(row=row, column=col, padx = 2, pady = 2)
  49.                 elif row == 0:
  50.                     # label columns
  51.                     labels = Label(root, width=3, text = str(col-1))
  52.                     labels.grid(row=row, column=col, padx = 2, pady =2)
  53.                 else:
  54.                     # use entry widget
  55.                     entrys = Entry(root, width=w)
  56.                     entrys.grid(row=row, column=col)
  57.                     cell = "%s%s" %(rowLabel[col], row)
  58.                     self.entriesDict[cell] = entrys
  59.                     # bind to left mouse click
  60.                     entrys.bind('<Button-1>', lambda e, cell=cell: self.onEvent(e, cell))
  61.                     # bind the object to a right mouse click
  62.                     entrys.bind('<Button-3>', lambda e, cell=cell: self.onEvent(e, cell))
  63.                     # bind the object to a return/enter press
  64.                     entrys.bind('<Return>', lambda e, cell=cell: self.returnKey(e, cell))
  65.         # start curser in row a column 0
  66.         self.entriesDict['a1'].focus()
  67. if __name__ == '__main__':
  68.     import sys
  69.     root = Tk()
  70.     root.title('S P R E A D S H E E T')
  71.     if len(sys.argv) != 3:
  72.         spreadsheet(root).grid()
  73.     else:
  74.         rows, cols = eval(sys.argv[1]), eval(sys.argv[2])
  75.         spreadsheet(root, rows, cols).grid()
  76.     root.mainloop() 
  77.  
  78.  
  79.  
Mar 28 '07 #1
Share this Question
Share on Google+
6 Replies


bartonc
Expert 5K+
P: 6,596
This spreadsheet is almost done, but there is some functionality that is driving me nuts.

For instance: a cell, for instance 'a0' is to have 'a0' as a string, but if something is entered like '4+5', that is also there. So, at any time, one could see the cell number a0 or they could click on it and have the equation show as well. Right now, I can make it show the equation, and evaluate it, or it can also show the cell number. But I can't make it so if the user goes back to that cell after showing the cell number that the equation will show. It will always show the cell number based on the event, but it retains the part that was in there because I don't want to 'delete' it.

How do I save the equation without showing it all the time? I'm thinking it should be saved to the dictionary I already have, but alas I'm stumped. Any ideas?
Now is the time to subclass the Entry widget to have an entryName and a value attribute. The widget (your subclass), itself would stort the value on an event (hint: bind to focusOut events as well as returnKey and enterKey events). Other events would then display either the (what do you call it? cell) name or the value.
Mar 28 '07 #2

TMS
100+
P: 119
TMS
I've been going over your reply for a couple of days. I'm asking for some clarification.

When you say subclass the Entry widget what do you mean? I don't dare use focusOut because my teacher is very, er, uh, rigid about his requirements. Here is the paragraph that describes the 2 strings:

"These cells allow the user to type in any Python expression, which will be maintained as a string associated with the cell. In fact, the suggested implementation is to give each cell two strings: an expression and a value. The expression is what the user types into the cell. The value is a string representation of the result of evaluating the expression and is what the users sees when they are not editing a cell. When the user finishes editing the cell (usually by pressing Return or TAb), that string will be evaluated (with eval()), converted to a string, and the result will be displayed in the cell.

Initially all cells start witha value of "", and empty stirng, so all cells initially appear blank. Clicking on a cell with a mouse button brings up the cell's expression, which the user may then modify and reenter with Return or Tab. When eval() is called, the cell string may contain any Python expression, string, integer, or float. It may also contain variables with correspond to the names of defined cells (e.g. A0, C17). In addition the Python math library should be made available. Nothing should crash the spreadsheet."

ok.. so in his words, that is what is required (he actually left something out, but I'm not there yet).

I'm thinking that I need to do something like make a new variable in the __init__ function, but I'm not sure how to initialize it. I think that is because I don't understand exactly how its being stored in the dictionary. I've tried to print the dictionary to better understand it, but I can't figure out how to get it to print.

So, I guess what I'm asking is this: How do I print the dictionary so I can see exactly how the data is being stored?
I assume the equation goes out of scope when return key is pressed. So, I need to make a variable in the __init__ file, but then I'm not sure how to access it, the syntax.

I'm liking the fact that you aren't giving me the answer, and appreciate the discussion so I can understand what is going on better. I seem to get to a certain point on the assignments, then I get stuck. I kinda think its the same type of problem I get stuck on each time and its just something I don't understand clearly yet. Thank you for your help.

TMS
Mar 31 '07 #3

bvdet
Expert Mod 2.5K+
P: 2,851
....
So, I guess what I'm asking is this: How do I print the dictionary so I can see exactly how the data is being stored?
.....
Hello TMS,

To print a class instance dictionary:
Expand|Select|Wrap|Line Numbers
  1. for key, value in cls_instance.__dict__.items():
  2.     print '%s = %s' % (key, value)
Mar 31 '07 #4

TMS
100+
P: 119
TMS
That isn't the dictionary that I was referring to. I initialize a dictionary, and I think I'm using it to save the strings, both equations and results. I want to see that dictionary. See the code above.


TMS
Mar 31 '07 #5

bvdet
Expert Mod 2.5K+
P: 2,851
That isn't the dictionary that I was referring to. I initialize a dictionary, and I think I'm using it to save the strings, both equations and results. I want to see that dictionary. See the code above.


TMS
Expand|Select|Wrap|Line Numbers
  1. >>> root = Tk()
  2. >>> a = spreadsheet(root)
  3. >>> print a.entriesDict
  4. {'b4': <Tkinter.Entry instance at 0x010F3A80>, 'd4': <Tkinter.Entry instance at 0x010F3F30>, 'a4': <Tkinter.Entry instance at 0x010F3800>, 'a1': <Tkinter.Entry instance at 0x010EB878>, 'a3': <Tkinter.Entry instance at 0x010EF170>, 'a2': <Tkinter.Entry instance at 0x010EF9B8>, 'b1': <Tkinter.Entry instance at 0x010EBAD0>, 'b2': <Tkinter.Entry instance at 0x010EF300>, 'b3': <Tkinter.Entry instance at 0x010EFDF0>, 'c3': <Tkinter.Entry instance at 0x010F3CB0>, 'c2': <Tkinter.Entry instance at 0x010EF2B0>, 'c1': <Tkinter.Entry instance at 0x010EF8A0>, 'c4': <Tkinter.Entry instance at 0x010F3BC0>, 'd2': <Tkinter.Entry instance at 0x010EFF58>, 'd3': <Tkinter.Entry instance at 0x010F3B20>, 'd1': <Tkinter.Entry instance at 0x010EF850>}
  5. >>> print a.entriesDict['b4']
  6. .17775232
  7. >>> 
Mar 31 '07 #6

TMS
100+
P: 119
TMS
OK, now I see what the problem is. I am assigning an entry widget as the value to the cell. I don't want to do that, but I don't know how else to write this.

What I do want is to assign the equation as the value to the cell name. Actually, whatever string is put in should be the value, not the entry widget itself. How do I do that?

I think this is where I assign the entry widget as the value of the cell, am I wrong?

Expand|Select|Wrap|Line Numbers
  1. self.entriesDict[cell] = entrys
  2.  
I was thinking that I would make a new variable in the __init__ function so it would carry throughout the class, like data or something like that. But when I tried it didn't work.
Apr 2 '07 #7

Post your reply

Sign in to post your reply or Sign up for a free account.