panda3d and tkinter communication

Hi all,
I’m developing a code that run a panda3d window using the mainloop of a tkinter application. I’d like to append the name of a cliked 3d object into a tikinter listbox. See the following code:

class Picker(DirectObject.DirectObject):
   def __init__(self):
      #setup collision stuff

      self.picker= CollisionTraverser()
      self.queue=CollisionHandlerQueue()

      self.pickerNode=CollisionNode('mouseRay')
      self.pickerNP=camera.attachNewNode(self.pickerNode)

      self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())

      self.pickerRay=CollisionRay()

      self.pickerNode.addSolid(self.pickerRay)

      self.picker.addCollider(self.pickerNode, self.queue)

      #this holds the object that has been picked
      self.pickedObj=None

      self.accept('mouse1', self.printMe)

   #this function is meant to flag an object as being somthing we can pick
   def makePickable(self,newObj):
      newObj.setTag('pickable','true')

   #this function finds the closest object to the camera that has been hit by our ray
   def getObjectHit(self, mpos): #mpos is the position of the mouse on the screen
      self.pickedObj=None #be sure to reset this
      self.pickerRay.setFromLens(base.camNode, mpos.getX(),mpos.getY())
      self.picker.traverse(render)
      if self.queue.getNumEntries() > 0:
         self.queue.sortEntries()
         self.pickedObj=self.queue.getEntry(0).getIntoNodePath()

         parent=self.pickedObj.getParent()
         self.pickedObj=None

         while parent != render:
            if parent.getTag('pickable')=='true':
               self.pickedObj=parent
               return parent
            else:
               parent=parent.getParent()
      return None

   def getPickedObj(self):
         return self.pickedObj

   def printMe(self):
		self.getObjectHit(base.mouseWatcherNode.getMouse())
		if not None: 
			name = self.pickedObj.getTag('name')
			print name
			# ab_listbox.insert(END, name)
		else:
			print self.pickedObj

class panda_window(ShowBase):
	def __init__(self):
		ShowBase.__init__(self)
		data = open_data_file("test.txt")
		mousePicker=Picker()
	
		for disk in data:
			self.draw(disk['name'],disk['x'],disk['y'],disk['z'])
	def draw(self,name,x,y,z):
		model = loader.loadModel("disk.egg")
		model.reparentTo(render)
		model.setPos(camera,x,y,z)
		model.setTag('name',name)		
		mousePicker.makePickable(model)


def task:
	panda_app.taskMgr.step
	after(1,task)

root = Tk()
panda_app = panda_window()
ab_listbox = Listbox(root)

ab_listbox.insert(END, "value-1")
ab_listbox.pack()

root.after(1,task)
root.mainloop()

I’d like to substitute the line print with the line insert (see the following two lines into the code above) but it seems not working.

         print name
         # ab_listbox.insert(END, name) 

Can anyone help me?
Thank you in advance,

Ale

There’s a couple things going on here.

The reason why your list box isn’t working is because of scope. In python when you define ab_listbox, its not treated as a global variable that all classes can access and you attempt to access it in the printMe method of your Picker class.

In mousePicker=Picker(), you make the object but since it’s not self.mousePicker, it goes out of scope and the picker object no longer exists.

The quick fix to this is make sure you use self.mousePicker and then assign ab_listbox to a variable inside your picker class with something like

class Picker:
  def __init__(self):
    self.listBox = None
  ...
  def setListBox(self, listbox):
    self.listBox = listBox

  ...
  def printMe(self):
    ...
    if self.listBox != None: self.listBox.insert(...)

Also I notice that your creating a new showbase and directObject. Showbase is a DirectObject. You can just use the same class. Also Showbase has it’s own tk root that you can already attach too. That way when you just run the “run()” tk will just work.

Good Luck