user3794512
user3794512

Reputation: 17

How can I create NEW Listboxes with a Button and collect all the data with a final submit Button in TKinter?

Okay so here is my problem. I am trying to create a very open ended user friendly Gui out of Tkinter. In short I made a button a function STAGE that creates a Listbox that has choose-able indexes. Then I can press the button SUBMIT that will print the selected keys.

BUT if I press ADD STAGE to make another listbox of the same value I CANNOT go back and edit or retrieve the selected values of the old listbox.

I understand that this is because of the listbox will have the same name so.....

from Tkinter import *
import tkMessageBox

class Insert_page(Frame):
    global i0
    global listbox  
    global Tech_option
    Tech_option=['Rolled Plate','extrude bar','as-cast','wire','Other','USER Details']
    i0=-1
    def __init__(self,parent):
        Frame.__init__(self,parent,background="white")




    self.parent=parent
    self.initUI()

    def initUI(self):
        self.parent.title("material Gui v2")
        self.grid(row=1,column=1)


        mButton=Button(self,text='Start Stages',command=self.stage).grid(row=2,column=5,sticky=W)        

        mButton3=Button(self,text='submit',command=self.submit).grid(row=9,column=1,sticky=W) 

    def stage(self): ######################HERE IS THE PROBLEM#########
        global i0
        i0+=1  

        stageFrame=Frame(self,bd=1,bg='red',relief=SUNKEN)
        stageFrame.grid(row = 1+5*i0, column = 1, rowspan = 5, columnspan = 7, sticky = W+E+N+S)


        stageVar = StringVar()
        OPTIONS = [""]+range(0,10)
        w = apply(OptionMenu, (stageFrame, stageVar) + tuple(OPTIONS))
        w.grid(row=1,column=1)


        stageLabel=Label(stageFrame,text='Stage')
        stageLabel.grid(row=1+5*i0,column=0,sticky=W)     

        mButton=Button(stageFrame,text='add Stage',command=self.stage).grid(row=9,column=1,sticky=W)

        listbox = Listbox(stageFrame,selectmode= MULTIPLE,exportselection=False) ######REPLACED CODE######
        listbox.grid(row=3+5*i0,column=2)

        for item in Tech_option :
            listbox.insert(END, item)

        mButton3=Button(self,text='submit',command=lambda: self.submit(listbox,Tech_option)).grid(row=9+5*i0,column=1,sticky=W) 
    ######REPLACED CODE######
    def submit(self,lb,option_list):
        Tech_select=[]
        for i in list(lb.curselection()):
            Tech_select.append(Tech_option[int(i)])
        print Tech_select


def main():
    mGui= Tk()
    mGui.geometry('800x600+200+200')

    menubar=Menu(mGui)
    filemenu=Menu(menubar,tearoff=0)
    filemenu.add_command(label="New")
    filemenu.add_command(label="Open")
    filemenu.add_command(label="SaveAs...")
    filemenu.add_command(label="Close")
    menubar.add_cascade(label='File',menu=filemenu)      

    mGui.config(menu=menubar)

    app=Insert_page(mGui)

    mGui.mainloop()



main()

I replaced it with this...

exec ('listbox_%s = Listbox(stageFrame,selectmode= MULTIPLE,exportselection=False)' % (i0)) in globals(), locals()
        exec ('listbox_%s.grid(row=3+5*i0,column=2)' % (i0)) in globals(), locals()

        for item in Tech_option :
            exec ('listbox_%s.insert(END, item)' % (i0)) in globals(), locals()



        mButton3=Button(self,text='submit',command=lambda: self.submit(eval('listbox_%s'%(i0)),Tech_option)).grid(row=9+5*i0,column=1,sticky=W) 

What it should do is create NEW listbox variables but all I get back when pressing submit is.

Traceback (most recent call last):
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1413, in __call__
    return self.func(*args)
  File "/home/xxxxxx/pythons/xxxxxxxx.py", line 78, in <lambda>
    mButton3=Button(self,text='submit',command=lambda: self.submit(eval('listbox_%s'%(i0)),Tech_option)).grid(row=9+5*i0,column=1,sticky=W)
  File "<string>", line 1, in <module>
NameError: name 'listbox_1' is not defined

If someone could help me with this that would be great.

Upvotes: 0

Views: 149

Answers (1)

furas
furas

Reputation: 142641

You need list of listbox to keep all lists from all stages.
Now in listbox you have only list from last created stage.

You will have to use lines like this (in different places)

self.all_listboxes = []

#---

self.all_listboxes.append( listbox )

#---

for one_list in self.all_listboxes:
     for x in one_list.curselection():

BTW: use self.listbox (in __init__) in place of global listbox.
The same with i0 and Tech_option.

We use class and self to not use global

Upvotes: 2

Related Questions