python 3.x - tkinter listbox insert error "invalid command name ".50054760.50055432" -


i have database of objects , can view items in database in listbox , there's button remove item , create item. creating item opens dialog window item class , item's data stored in database. have reproduced problem simple duplicate of set-up (see code below).

every time add new item, addition successful (it's there next time open database dialog), listbox doesn't insert item, , when close database dialog following error:

exception in tkinter callback traceback (most recent call last):
file "c:\python33\lib\tkinter__init__.py", line 1442, in call return self.func(*args) file "", line 21, in addrecord file "c:\python33\lib\tkinter__init__.py", line 2604, in insert self.tk.call((self._w, 'insert', index) + elements) _tkinter.tclerror: invalid command name ".50054760.50055432"

the same problem doesn't come if try create object , populate values without invoking inputs gui (which necessary process of inserting things database). i've seen similar error in thread (sorry, can't seem find again), problem multithreading. i'm not aware of threading i'm doing , don't want download yet package handle tkinter threading. ideas? workarounds? i'm using python v3.3 , 64-bit windows 7, if helps.

here's simplified database code:

import tkinter import traceback  # test ========================================================================= class test:     def __init__(self):         """a database of objects' ids , values."""          self.data = {1: 'a', 2: 'b', 3: 'c'}      #---------------------------------------------------------------------------     def addrecord(self):         """opens new item editing , saves ability         database."""         print('hi0')         newitem = otherobject()         newitem.create(self.root)          print('hi1')         self.data[newitem.id] = newitem.value         print('hi2')         self.listbox.insert(tkinter.end, self.formatitem(newitem.id))         print('hi3')      #---------------------------------------------------------------------------     def delrecord(self):         """removes selected item database."""          try:             index = self.listbox.curselection()[0]             selection = self.listbox.get(index)         except:             return         id = int(selection.split(':')[0])          self.data.pop(id)         self.listbox.delete(index)      #---------------------------------------------------------------------------     def dataframe(self, master):         """assembles tkinter frame scrollbar view database objects.         (returns frame, scrollbar widget, listbox widget)          master: (tk or toplevel) tkinter master widget."""          frame = tkinter.frame(master)          # scrollbar         scrollbar = tkinter.scrollbar(frame)         scrollbar.pack(side=tkinter.left, fill=tkinter.y)          # listbox         listbox = tkinter.listbox(frame, yscrollcommand=scrollbar.set)         listbox.pack(side=tkinter.left, fill=tkinter.both)          # fill listbox         id in self.data:             listbox.insert(tkinter.end, self.formatitem(id))          return (frame, listbox, scrollbar)      #---------------------------------------------------------------------------     def destroylb(self, e):         line in traceback.format_stack():             print(line.strip())      #---------------------------------------------------------------------------     def formatitem(self, id):         """creates nice string representation of item in database."""          return '{0}:{1}'.format(id, self.data[id])      #---------------------------------------------------------------------------     def listboxselect(self, e):         """manages events when selection changes in database interface.          e: (event) tkinter event."""          try:             selection = self.listbox.get(self.listbox.curselection()[0])         except:             return          # set description label         id = int(selection.split(':')[0])         self.lblstr.set(self.data[id])      #---------------------------------------------------------------------------     def view(self):         """displays database interface."""          self.root = tkinter.tk()          # listbox frame         self.frame, self.listbox, self.scrollbar = self.dataframe(self.root)         self.frame.grid(column=0, row=0)         self.listbox.bind('<<listboxselect>>', self.listboxselect)         self.listbox.bind('<destroy>', self.destroylb)          # record display frame         self.lblstr = tkinter.stringvar()         self.lbl = tkinter.label(self.root, textvariable=self.lblstr)         self.lbl.grid(column=1, row=0, sticky=tkinter.n)          # buttons frame         self.frame_btn = tkinter.frame(self.root)         self.frame_btn.grid(row=1, columnspan=2, sticky=tkinter.e+tkinter.w)          # 'create new' button         self.btn_new = tkinter.button(             self.frame_btn, text='+', command=self.addrecord)         self.btn_new.grid(row=0, column=0)          # 'delete record' button         self.btn_del = tkinter.button(             self.frame_btn, text='-', command=self.delrecord)         self.btn_del.grid(row=0, column=1)          # display         self.root.mainloop() # test =========================================================================  # otherobject ================================================================== class otherobject:     """an object id , value."""      def __init__ (self):         self.id = 0         self.value = ''      #---------------------------------------------------------------------------     def create(self, master=none):         """open dialog user entry new object id , value.          master: (tk or toplevel) tkinter master widget."""          self.stuff = tkinter.toplevel(master)          # id         tkinter.label(self.stuff, text='id: ').grid(row=0, column=0)          self.idvar = tkinter.stringvar(self.stuff)         self.idvar.set(self.id)         idwidget = tkinter.entry(self.stuff, textvariable=self.idvar)         idwidget.grid(row=0, column=1)          # value         tkinter.label(self.stuff, text='value: ').grid(row=1, column=0)          self.valuevar = tkinter.stringvar(self.stuff)         self.valuevar.set(self.value)         valuewidget = tkinter.entry(self.stuff, textvariable=self.valuevar)         valuewidget.grid(row=1, column=1)          # ok button         tkinter.button(self.stuff, text='ok', command=self.ok).grid(row=2)          self.stuff.mainloop()      #---------------------------------------------------------------------------     def ok(self):         try: self.id = int(self.idvar.get())         except: self.id = 0         self.value = self.valuevar.get()          self.stuff.destroy() # otherobject ================================================================== 

thanks in advance

you creating more 1 instance of tk. tkinter not designed work , unexpected behavior. need refactor code create instance of tk once. if need multiple windows, create instances of toplevel.

... time passes ... code in question gets updated ...

in updated version of question creating 1 instance of tk, , instances of toplevel. good. however, calling mainloop more once problem. worse, you're redefining self.root no doubt part of problem. must call mainloop once on entirety of program.


Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

javascript - addthis share facebook and google+ url -

ios - Show keyboard with UITextField in the input accessory view -