Windows python/Pmw-tkinter problem

Bruce Davis brucedavis at cableone.net
Fri Oct 24 16:15:55 EDT 2003



I'm having a problem on windows (both 2000 and XP) with a multi-threaded
tkinter gui application. The problem  appears to be a deadlock condition
when a child thread pops up a
Pmw dialog window in the context of a main window.   The problem does not
occur on HPUX or Linux.   The following  simple example code  illustrates
the problem and the work around
I've come up with; However, I'd like, very much, to get rid of the kludgy
work around.

Running the following program without input options works (my work around)

    WindowsProblem.py

Running the program with a '-r' option causes a deadlock condition and the
program hangs.

    WindowsProblem.py  -r

Anyone had a similar problem or know of  a solution/patch for  this problem?

Thanks,

-Bruce Davis

BTW   I'm currently using Python 2.3.2 - the problem also occurs on Python
2.2. And, again, there is no need for the work around on HPUX or Linux. This
seems
to be a windows type of thing.






#!/usr/bin/env python

import  thread, threading, Pmw, time, sys
from Tkinter import *


class mainWindow:

     def __init__(self, root, winKludge):
      self.root = root

      # Create a simple frame with one button
      fr = Frame(self.root)
      button= Button(fr, text='Click to exit', command=self.NOP)
      button.grid(row=0, column=0)
      fr.grid(row=0, column=0)

      # start a worker thread so as not to block the main window thread.
      thread.start_new_thread(workerThread, (root, winKludge))

     def NOP(self):
          self.root.destroy()

def workerThread(parent, winKludge):
      # sleep  a while and pop up a dialog window.
      time.sleep(2.0)
      pu = popup(parent, winKludge)
      pu.show()


class popup:

     def __init__(self, root, winKludge):
      self.root = root
      self.winKludge = winKludge


      if self.winKludge and  sys.platform=='win32':
           self.kludgeMutex = threading.Lock()
           self.kludgeMutex.acquire()
           self.condEvent = threading.Condition()
           self.condEvent.acquire(1)
           root.after_idle(self.windowsKludge)
           self.condEvent.wait(30.0)
            self.condEvent.release()


          self.win = Pmw.MessageDialog(root,
           separatorwidth=4,
           message_text='Test',
           buttons=('Click to exit',),
           command=self.callBack,
           )
          self.win.withdraw()

 def windowsKludge(self):
        # need to block the main window thread to prevent the program hang
when creating the popup
       self.condEvent.acquire(1)
       self.condEvent.notify()
       self.condEvent.release()
       self.kludgeMutex.acquire()



 def show(self):
      if self.winKludge and sys.platform=='win32':
           self.kludgeMutex.release()
           self.root.after_idle(self.win.activate)
           self.wait()
        else:
               self.win.activate(globalMode='nograb',
geometry='centerscreenalways')

 def quitter(self):
      if self.winKludge and sys.platform=='win32':
           self.condEvent.acquire(1)
           self.condEvent.notify()
           self.condEvent.release()
      self.win.deactivate()

 def wait(self, timeOut=2000):
      self.condEvent.acquire(1)
      self.condEvent.wait(timeOut)
      self.condEvent.release()

 def callBack(self, result):
      self.quitter()




if __name__ == '__main__':

 usageStr="""

  WindowsProblem [r] [h]
  Simple program to demonstrate a problem that  occurs on windows (2000 and
XP)
  and a work around.  The program works without the work around on HPUX and
Linux boxes.


  Input options:
  -h - displays this help message
  -r - reproduce the problem

  Without the -r option, there is no problem.
  With the -r option, the window appears to deadlock and hang forever.

 """

 import getopt
 try:
  optlist,args = getopt.getopt(sys.argv[1:],"hr")
 except getopt.error,info:
  Print (usageStr)
  sys.exit(1)

 winKludge = 1
 for opt in optlist:
  if opt[0] == '-h':
   print usageStr
   sys.exit(0)
  elif opt[0] == '-r':
   winKludge = 0

 # Create the main window
 root = Tk()
 mainWindow(root, winKludge)
 root.mainloop()






More information about the Python-list mailing list