[vtkusers] One solution to manage several vtkTkRenderWidget

Thinnes alexandre.thinnes at aist.go.jp
Fri Dec 24 01:46:07 EST 2004


Hello vtkUsers,

I had some problems about managing several vtkTkRenderWidget in Python.
I posted a message about that few days ago.
Mr David Gobbi helped me a lot to find this solution.
He said: "Each program can only have one Tk object. Instead, derive one
your windows from a "Toplevel" widget"

So in my precedent architecture, I had more than one Tk Object ( 3 Tk
objects, Triplan, Bouton and Render) I needed to delete two of them.

The following is the WRONG architecture:
Each module corresponding to one part of the interface ( Here there are
4 modules ):

######################################################################
#testfunc.py

from Tkinter import *
from vtkTkRenderWidget import *
import triplantest
import bouton
import render

class Functions:

   def __init__(self, myParent):
      print "functions class created"
# If you comment the self.render line. The button will open the
triplantest window
      self.render = render.Render(self, myParent)

      self.bouton = bouton.Bouton(self)
      self.triplan = triplantest.Triplan(self)

## Procedure:  show
# this procedure is call to show on the screen the windows winname
   def show(self, winname):
      winname.deiconify()
      self.affichageTriplan()

## Procedure:  affichageTriplan
# This procedure setup the slice image inside triplan interface

   def affichageTriplan(self):

      self.renderWidget = vtkTkRenderWidget(self.triplan.frame1)
      self.renderWidget.pack(expand='true',fill='both')


if __name__ == '__main__':

   root = Tk()
   function = Functions(root)
   function.triplan.withdraw()
   root.mainloop()

#######################################################################
#render.py

from vtkTkRenderWidget import *
from vtkpython import *
from Tkinter import *

class Render:

   def __init__(self, myFunctions, myParentFunction):

      self.functions = myFunctions
      myParentFunction.title("test vtkTkRenderWidget")

      self.viewer = Frame(myParentFunction, borderwidth = 2, relief =
"ridge")
      self.renderWidget = vtkTkRenderWidget(self.viewer)

      self.viewer.pack(expand='true',fill='both')
      self.renderWidget.pack(expand='true',fill='both')

##########################################################################

#triplantest.py

from Tkinter import *

class Triplan(Tk):
   def __init__(self, myFct):
      Tk.__init__(self)

      self.functions = myFct
      self.title("Frame for vtkSliceWidget")

      self.mainframe = Frame(self)
      self.frame1 = Frame(self.mainframe, relief="ridge", borderwidth=2)

      self.frame1.pack(expand='true',fill='both')
      self.mainframe.pack(expand='true',fill='both')

###############################################################
#bouton.py

from Tkinter import *
class Bouton(Tk):

   def __init__(self, myFunctions):
      Tk.__init__(self)
      self.functions = myFunctions
      self.title("Click On Button")
      self.frame = Frame(self)
      self.bouton = Button(self.frame, text = "click \nhere",
       command = lambda:
         self.functions.show(self.functions.triplan)
      )

      self.frame.pack(expand='true',fill='both')
      self.bouton.pack(expand='true',fill='both')

######################################################################

If you run "python testfunc.py" you will see the error.

********************************************************************************************

Indeed, I must create different Toplevel, derivate of the Main Tk
Object.
The GOOD architecture is the following:


###########################################################################

#testfunc.py

from Tkinter import *
from vtkTkRenderWidget import *
import triplantest
import bouton
import render

class Functions:

   def __init__(self, myParent):
       # You must define some toplevel. All off them derivate from
myParent. Here is Tk Object
      self.top = Toplevel(myParent)
      self.top2 = Toplevel(myParent)

      #The main window is build in the Original Tk. If it's destroy, the
application will be destroy
      self.render = render.Render(self, myParent)

      # Others windows my be declare in the toplevel you create before.
      self.bouton = bouton.Bouton(self.top, self)
      self.triplan = triplantest.Triplan(self.top2, self)

## Procedure:  show
# this procedure is call to show on the screen the windows winname
   def show(self, winname):
      winname.deiconify()
      self.affichageTriplan()

## Procedure:  affichageTriplan
# This procedure setup the slice image inside triplan interface

   def affichageTriplan(self):
       #take care, when you call widget in derivate windows. The widget
is part of the toplevel
      self.renderWidget1 = vtkTkRenderWidget(self.top2.frame1)
      self.renderWidget1.pack(expand='true',fill='both')


if __name__ == '__main__':

   root = Tk()
   function = Functions(root)
   function.top2.withdraw()
   root.mainloop()

################################################################################

#render.py

from vtkTkRenderWidget import *
from vtkpython import *
from Tkinter import *

class Render:

   def __init__(self, myFunctions, myParentFunction):

      self.functions = myFunctions
      myParentFunction.title("test vtkTkRenderWidget")

      self.viewer = Frame(myParentFunction, borderwidth = 2, relief =
"ridge")
      self.renderWidget = vtkTkRenderWidget(self.viewer)

      self.viewer.pack(expand='true',fill='both')
      self.renderWidget.pack(expand='true',fill='both')

################################################################################

#bouton.py

from Tkinter import *

class Bouton(Toplevel):

   def __init__(self, test, myFunctions):
      #myFunctions is the link to the procedure in testfunc.py
      #test is the toplevel
      self.functions = myFunctions
      test.title("Click On Button")
      test.frame = Frame(test)
      test.bouton = Button(test.frame, text = "click \nhere",
       command = lambda:
         self.functions.show(self.functions.top2)
      )

      test.frame.pack(expand='true',fill='both')
      test.bouton.pack(expand='true',fill='both')

####################################################################
#triplantest.py
from Tkinter import *
from vtkTkRenderWidget import *
from vtkpython import *

class Triplan(Toplevel):
   def __init__(self, test, myFct):
      #myFct is the link to the procedure in testfunc.py
      # test is the toplevel.
      self.functions = myFct
      test.title("Frame for vtkSliceWidget")

      test.mainframe = Frame(test)
      test.frame1 = Frame(test.mainframe, relief="ridge", borderwidth=2)

      test.frame1.pack(expand='true',fill='both')
      test.mainframe.pack(expand='true',fill='both')

######################################################################

This is the way I found to solve my problems.  I don't think it's the
only one.
I hope this mail could help other people.
I want to thanks again David Gobbi. Without him, I think, I would still
search a solution. ^_^

bye
Alexandre






More information about the vtkusers mailing list