0

Firstly apologises for the length of code but I wanted to show it all.

I have an interface that looks like this:

Table interface

When I change the third Option Menu to "List" I will add in the option to have 'n' values (not shown). I then require 'n' columns where the user can input their values.

I also have the problem where there may be 'n' amount of rows depending on a text file opened by the interface.

I am therefore wondering if it possible (as I'm having difficulties not repeating the same values in boxes and now I require 'n' columns) to add 'n' amount of rows and columns as my code shows with just adding 4 columns. I can read the amount of rows ok but have trouble returning all of these values depending on how many rows there are. So far I can do one row..

Thank you!

def numberwritten(number): 
    fg = number.get()
    print fg

numbers = [StringVar() for i in xrange(4) ] #Name available in global scope. Need to add other rows?
for i in numbers: 
    i.trace('w',lambda a,b,c,n=i: numberwritten(n) ) 


def ChoiceBox(choice):


    co_ord = str(frame_table.grid_size())
    col, rows = map(float, co_ord.strip('()').split(','))
    rows = int(rows)
    if choice == "Fixed":
        empty1.destroy()
        #choice_frame.grid_forget()     
        tkMessageBox.showinfo("Message", "No optimisation, value fixed.")
    elif choice == "List":
        column = 7
        for i in xrange(4): 
        choice_title = Label(frame_table, text='Value %g'% float(i+1), bg='white', borderwidth=0, width=10) 
            choice_title.grid(row=1, column=column+i, sticky="nsew", padx=1, pady=1) 
            boxes=[]

        for i in xrange(4):
            for j in range(2, rows): 
                box=Entry(frame_table,bg='white',borderwidth=0,textvariable=numbers[i], width=10, justify="center") # Here I'm having problems with rows 
                box.grid(row=j,column=column+i, sticky='nsew', padx=1, pady=1) 
        boxes.append(box)
        box1,box2,box3,box4=boxes


    elif choice == "Interval" or "Optimisation":
        for i in xrange(2): 
            choice_title1 = Label(frame_table, text='Min Value', bg='white', borderwidth=0)
            choice_title1.grid(row=0, column=column, sticky="nsew", padx=1, pady=1)
            choice_title2 = Label(frame_table, text='Max Value', bg='white', borderwidth=0)
            choice_title2.grid(row=0, column=column+1, sticky="nsew", padx=1, pady=1)

            boxes=[]

        for i in xrange(2): 
            box=Entry(frame_table,bg='white',borderwidth=0,textvariable=numbers[i]) 
            box.grid(row=rows+1,column=i, sticky='ew', padx=1, pady=1) 
            boxes.append(box)
            box1,box2,box3,box4=boxes

UPDATE: I've advanced slightly and the section in ChoiceBox which is now under a class Window: is ChoiceBox(self, choice), I have the following section where I need to change the commented line to accept 'n' amount of boxes.

column = 7
        for i in xrange(self.number_boxes): 
            choice_title = Label(self.frame_table, text='Value %g'% float(i+1), bg='white', borderwidth=0, width=10) 
            choice_title.grid(row=1, column=column+i, sticky="nsew", padx=1, pady=1) 
        boxes=[]

        for i in xrange(self.number_boxes):
            for j in range(2, rows): 
                box=Entry(self.frame_table,bg='white',borderwidth=0,textvariable=numbers[i], width=10, justify="center") 
                box.grid(row=j,column=column+i, sticky='nsew', padx=1, pady=1) 
            boxes.append(box)
        #box1,box2,box3,box4=boxes

I still however then have the problem of using numberwritten including the first few lines of code in original example to completely extract a list of values, preferably for each row.

user2063
  • 975
  • 4
  • 15
  • 35
  • When you write 'change the second Option Menu to "List" ', do you really mean the third option menu (in the column "choice")? Also, how many columns might you add? You say "n". Can "n" be 100? If "n" can be more than just a few this solution won't scale very well from a usability perspective. – Bryan Oakley Jun 29 '12 at 13:40
  • Sorry I do mean third, question edited. n would not be a huge number, maybe at max 20 or so. – user2063 Jun 29 '12 at 13:46
  • You do realize that with a very conservative 100 pixels per column you're talking about adding 2000 pixels to the width of your form. Are you sure you want to go down this road? – Bryan Oakley Jun 29 '12 at 17:06
  • I've been given the task to add these columns according to the number of rows so yes that's what I'm planning on doing. Just been getting very confused about how to do it according to the no. of rows/columns and vice versa. – user2063 Jul 02 '12 at 06:16
  • I have changed my answer slightly to show were exactly it is I'm needing the help now. It's a case of getting a list of values for each row but the number of columns may be 'n' (provided by the user) and the number of rows = rows as that may alter depending on the text file opened. – user2063 Jul 02 '12 at 14:21

1 Answers1

1

While I'm not convinced that you've found the easiest way to express your interface yet, to do what you want is relatively simple.

Conceptually, to add an entry for editing a value you have to define (and store a reference to) an object that acts as the model for the value. You then define the widget (or widgets) that will manipulate that value. Then you add such key bindings as are necessary (often none; the defaults are pretty good). Finally, you add the widget to the overall user interface (via the grid method, for example). However, this does mean that you have to design your overall code to handle a model whose size is not fixed. (Removing an entry is the reverse process, of course.)

It's a good idea to start refactoring your code into smaller pieces that do smaller pieces of this overall task. For example, write a function to just create a model, an entry widget, to add that widget to the GUI, and to return the model object. Everywhere else that needs to create such a coupled entry can then ask this expert function to do the job for them, so you can get it right, once. By breaking things up into smaller pieces with very clearly defined tasks, it becomes much easier to focus on the more complex logic aspects instead of getting bogged down with the (long, boring) details of widget management.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215