]> 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
 """
 
 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):
     def __init__(self, *args, **kwds):
-        # begin wxGlade: FrameSimpleDelayed.__init__
-        kwds["style"] = wx.DEFAULT_FRAME_STYLE
         wx.Frame.__init__(self, *args, **kwds)
         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)
         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):
     """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)
         self.Bind(wx.EVT_CLOSE, self.handleClose)
-    
+
     def setLog(self, log):
         self.log = log
 
     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():
         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.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
         """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
 
         return jobID
 
+
     def handleAbort(self, event): 
     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.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()
         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) )
         try:
             result = delayedResult.get()
         except Exception, exc:
             self.log( "Result for job %s raised exception: %s" % (jobID, exc) )
-            self.jobID += 1
             return
         
         # output result
             return
         
         # output result
@@ -133,32 +121,32 @@ class FrameSimpleDelayed(FrameSimpleDelayedGlade):
         # get ready for next job:
         self.buttonGet.Enable(True)
         self.buttonAbort.Enable(False)
         # 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
     """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): 
         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 )
         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."""
         """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
         
         """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))
         # output result
         self.log( "Got result for job %s: %s" % (self.jobID, result) )
         self.textCtrlResult.SetValue(str(result))