سؤال

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.

هل كانت مفيدة؟

المحلول

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top