]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/demo/DelayedResult.py
fixed child windows scrolling to use wxSIZE_ALLOW_MINUS_ONE
[wxWidgets.git] / wxPython / demo / DelayedResult.py
index f72fab5b3152869c019d73e8244c77e82bb6d38d..f5631880d9b8332d422b73f4d57309059e7b4762 100644 (file)
@@ -16,62 +16,50 @@ not even possible to Abort.
 """
 
 import wx
-from wx.lib.delayedresult import startWorker
+import wx.lib.delayedresult as delayedresult
 
-class FrameSimpleDelayedGlade(wx.Frame):
+
+class FrameSimpleDelayedBase(wx.Frame):
     def __init__(self, *args, **kwds):
-        # begin wxGlade: FrameSimpleDelayed.__init__
-        kwds["style"] = wx.DEFAULT_FRAME_STYLE
         wx.Frame.__init__(self, *args, **kwds)
-        self.checkboxUseDelayed = wx.CheckBox(self, -1, "Use delayedresult")
-        self.buttonGet = wx.Button(self, -1, "Get")
-        self.buttonAbort = wx.Button(self, -1, "Abort")
-        self.slider = wx.Slider(self, -1, 0, 0, 10, size=(100,-1), style=wx.SL_HORIZONTAL|wx.SL_AUTOTICKS)
-        self.textCtrlResult = wx.TextCtrl(self, -1, "", style=wx.TE_READONLY)
+        pnl = wx.Panel(self)
+        self.checkboxUseDelayed = wx.CheckBox(pnl, -1, "Using delayedresult")
+        self.buttonGet = wx.Button(pnl, -1, "Get")
+        self.buttonAbort = wx.Button(pnl, -1, "Abort")
+        self.slider = wx.Slider(pnl, -1, 0, 0, 10, size=(100,-1),
+                                style=wx.SL_HORIZONTAL|wx.SL_AUTOTICKS)
+        self.textCtrlResult = wx.TextCtrl(pnl, -1, "", style=wx.TE_READONLY)
 
-        self.__set_properties()
-        self.__do_layout()
+        self.checkboxUseDelayed.SetValue(1)
+        self.checkboxUseDelayed.Enable(False)
+        self.buttonAbort.Enable(False)
 
+        vsizer = wx.BoxSizer(wx.VERTICAL)
+        hsizer = wx.BoxSizer(wx.HORIZONTAL)
+        vsizer.Add(self.checkboxUseDelayed, 0, wx.ALL, 10)
+        hsizer.Add(self.buttonGet, 0, wx.ALL, 5)
+        hsizer.Add(self.buttonAbort, 0, wx.ALL, 5)
+        hsizer.Add(self.slider, 0, wx.ALL, 5)
+        hsizer.Add(self.textCtrlResult, 0, wx.ALL, 5)
+        vsizer.Add(hsizer, 0, wx.ALL, 5)
+        pnl.SetSizer(vsizer)
+        vsizer.SetSizeHints(self)
+        
         self.Bind(wx.EVT_BUTTON, self.handleGet, self.buttonGet)
         self.Bind(wx.EVT_BUTTON, self.handleAbort, self.buttonAbort)
-        # end wxGlade
 
-    def __set_properties(self):
-        # begin wxGlade: FrameSimpleDelayed.__set_properties
-        self.SetTitle("Simple Examle of Delayed Result")
-        self.checkboxUseDelayed.SetValue(1)
-        self.checkboxUseDelayed.Enable(False)
-        self.buttonAbort.Enable(False)
-        # end wxGlade
-
-    def __do_layout(self):
-        # begin wxGlade: FrameSimpleDelayed.__do_layout
-        sizerFrame = wx.BoxSizer(wx.VERTICAL)
-        sizerGetResult = wx.BoxSizer(wx.HORIZONTAL)
-        sizerUseDelayed = wx.BoxSizer(wx.HORIZONTAL)
-        sizerUseDelayed.Add(self.checkboxUseDelayed, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 5)
-        sizerFrame.Add(sizerUseDelayed, 1, wx.EXPAND, 0)
-        sizerGetResult.Add(self.buttonGet, 0, wx.ADJUST_MINSIZE, 0)
-        sizerGetResult.Add(self.buttonAbort, 0, wx.ADJUST_MINSIZE, 0)
-        sizerGetResult.Add(self.slider, 0, wx.ADJUST_MINSIZE, 0)
-        sizerGetResult.Add(self.textCtrlResult, 0, wx.ADJUST_MINSIZE, 0)
-        sizerFrame.Add(sizerGetResult, 1, wx.ALL|wx.EXPAND, 5)
-        self.SetAutoLayout(True)
-        self.SetSizer(sizerFrame)
-        sizerFrame.Fit(self)
-        sizerFrame.SetSizeHints(self)
-        self.Layout()
-        # end wxGlade
 
 
-class FrameSimpleDelayed(FrameSimpleDelayedGlade):
+
+class FrameSimpleDelayed(FrameSimpleDelayedBase):
     """This demos simplistic use of delayedresult module."""
     
     def __init__(self, *args, **kwargs):
-        self.jobID = 1
-        FrameSimpleDelayedGlade.__init__(self, *args, **kwargs)
+        FrameSimpleDelayedBase.__init__(self, *args, **kwargs)
+        self.jobID = 0
+        self.abortEvent = delayedresult.AbortEvent()
         self.Bind(wx.EVT_CLOSE, self.handleClose)
-    
+
     def setLog(self, log):
         self.log = log
 
@@ -80,50 +68,50 @@ class FrameSimpleDelayed(FrameSimpleDelayedGlade):
         app, so worker thread continues and sends result to dead frame; normally
         your app would exit so this would not happen."""
         if self.buttonAbort.IsEnabled():
-            self.Hide()
-            import time
-            time.sleep(5)
+            self.log( "Exiting: Aborting job %s" % self.jobID )
+            self.abortEvent.set()
         self.Destroy()
             
     def handleGet(self, event): 
         """Compute result in separate thread, doesn't affect GUI response."""
         self.buttonGet.Enable(False)
         self.buttonAbort.Enable(True)
+        self.abortEvent.clear()
+        self.jobID += 1
+        
+        self.log( "Starting job %s in producer thread: GUI remains responsive"
+                  % self.jobID )
+        delayedresult.startWorker(self._resultConsumer, self._resultProducer, 
+                                  wargs=(self.jobID,self.abortEvent), jobID=self.jobID)
 
-        self.log( "Starting job %s in producer thread: GUI remains responsive" % self.jobID )
-        startWorker(self.__handleResult, self.__resultCreator, 
-                    wargs=(self.jobID,), jobID=self.jobID)
                         
-    def __resultCreator(self, jobID):
+    def _resultProducer(self, jobID, abortEvent):
         """Pretend to be a complex worker function or something that takes 
         long time to run due to network access etc. GUI will freeze if this 
         method is not called in separate thread."""
         import time
-        time.sleep(5)
+        count = 0
+        while not abortEvent() and count < 50:
+            time.sleep(0.1)
+            count += 1
         return jobID
 
+
     def handleAbort(self, event): 
-        """Abort actually just means 'ignore the result when it gets to 
-        handler, it is no longer relevant'. We just increase the job ID, 
-        this will let handler know that the result has been cancelled."""
+        """Abort the result computation."""
         self.log( "Aborting result for job %s" % self.jobID )
         self.buttonGet.Enable(True)
         self.buttonAbort.Enable(False)
-        self.jobID += 1
+        self.abortEvent.set()
+
         
-    def __handleResult(self, delayedResult):
-        # See if we still want the result for last job started
+    def _resultConsumer(self, delayedResult):
         jobID = delayedResult.getJobID()
-        if jobID != self.jobID:
-            self.log( "Got obsolete result for job %s, ignored" % jobID )
-            return
-
-        # we do, get result:
+        assert jobID == self.jobID
         try:
             result = delayedResult.get()
         except Exception, exc:
             self.log( "Result for job %s raised exception: %s" % (jobID, exc) )
-            self.jobID += 1
             return
         
         # output result
@@ -133,32 +121,32 @@ class FrameSimpleDelayed(FrameSimpleDelayedGlade):
         # get ready for next job:
         self.buttonGet.Enable(True)
         self.buttonAbort.Enable(False)
-        self.jobID += 1
 
 
-class FrameSimpleDirect(FrameSimpleDelayedGlade):
+class FrameSimpleDirect(FrameSimpleDelayedBase):
     """This does not use delayedresult so the GUI will freeze while
     the GET is taking place."""
     
     def __init__(self, *args, **kwargs):
         self.jobID = 1
-        FrameSimpleDelayedGlade.__init__(self, *args, **kwargs)
+        FrameSimpleDelayedBase.__init__(self, *args, **kwargs)
         self.checkboxUseDelayed.SetValue(False)
                 
     def setLog(self, log):
         self.log = log
         
     def handleGet(self, event): 
-        """Use delayedresult, this will compute
-        result in separate thread, and won't affect GUI response. """
+        """Use delayedresult, this will compute result in separate
+        thread, and will affect GUI response because a thread is not
+        used."""
         self.buttonGet.Enable(False)
         self.buttonAbort.Enable(True)
 
         self.log( "Doing job %s without delayedresult (same as GUI thread): GUI hangs (for a while)" % self.jobID )
-        result = self.__resultCreator(self.jobID)
-        self.__handleResult( result )
+        result = self._resultProducer(self.jobID)
+        self._resultConsumer( result )
 
-    def __resultCreator(self, jobID):
+    def _resultProducer(self, jobID):
         """Pretend to be a complex worker function or something that takes 
         long time to run due to network access etc. GUI will freeze if this 
         method is not called in separate thread."""
@@ -170,7 +158,7 @@ class FrameSimpleDirect(FrameSimpleDelayedGlade):
         """can never be called"""
         pass
         
-    def __handleResult(self, result):
+    def _resultConsumer(self, result):
         # output result
         self.log( "Got result for job %s: %s" % (self.jobID, result) )
         self.textCtrlResult.SetValue(str(result))