Question #293847 on Sikuli changed: https://answers.launchpad.net/sikuli/+question/293847
Description changed to: *************** a revised version of the provided sample code by RaiMan ************* *** comments: - with such a solution it is not possible to kill the running SwingWorker thread (the python interpreter simply ignores the bgThread.cancel(True) request. (the problems with the wait() are fixed in the next 1.1.1 - see revised sample) - to use a stop button, to end a script only works, if the script does not make continuous use of the mouse (you will not get a chance to click the button). a good alternative is a stop hotkey (see revised sample) - to add a global kill option for the SwingWorker thread, you either have to run the script via subprocess module or implement something like that hack: https://web.archive.org/web/20130503082442/http://mail.python.org/pipermail/python-list/2004-May/281943.html - another option is to make the script aware of a stop request (as done in the revised sample below) - the triggered script should not run into an infinite loop or wait, since this can only be stopped by aborting the wrapping script or even the IDE - the script should be tested before adding it into such a wrapper, because most errors simply do not produce any helpful output (an option is to make the script run standalone and then use runScript() in the wrapper) - print statements should only have one parameter, otherwise printouts from the different threads get mangled (use the Python string formatting ""%() to assure that - see sample) - the start button should only be activated again by code, that is triggered by the thread on termination (in the revised example I use the done() callback for that (otherwise it might be possible to trigger a new run, while one is still running) from javax.swing import JButton, JFrame, JTextField, JPanel from java.lang import Runnable, InterruptedException from java.util.concurrent import ExecutionException from javax.swing import SwingWorker, SwingUtilities from java.lang import * from java.awt.event import ActionListener, WindowAdapter import threading class BgTask(SwingWorker): def __init__(self, gui): self.gui = gui SwingWorker.__init__(self) self.stopRun = False def shouldStop(self, event=None): self.stopRun = True def someInit(self): print "**** started" Env.addHotkey("x", KeyModifier.CTRL+KeyModifier.ALT, self.shouldStop) # @Override def doInBackground(self): self.someInit() for i in range(10): if self.stopRun: break # for 1.1.x before 2016-05-21 #App.pause(1) wait(1) self.showState("%d ** running - State:" % (i)) def showState(self, msg): if self.stopRun: print "%s - shouldStop reveived" % (msg) else: print "%s - %s" % (msg, self.getState()) # @Override def done(self): self.gui.hasEnded() print "**** ended" class Example: def __init__(self): frame = JFrame("Automated Testing") frame.setSize(200, 150) frame.addWindowListener(Adapter()) frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) frame.setAlwaysOnTop(True) pnl=JPanel() frame.add(pnl) self.startBtn = JButton('Start Automation', actionPerformed=self.startRun) self.stopBtn = JButton('Stop', actionPerformed=self.stopRun) pnl.add(self.startBtn) pnl.add(self.stopBtn) self.stopBtn.enabled = False frame.pack() frame.setVisible(True) def startRun(self,event): self._setButtonStates(True) self.bgTask = BgTask(self) self.bgTask.execute() def stopRun(self, event): #self.bgTask.cancel(True) # generally no effect self.bgTask.shouldStop() self.bgTask = None def _setButtonStates(self, activated): self.stopBtn.enabled = activated self.startBtn.enabled = not activated def hasEnded(self): self._setButtonStates(False) class Adapter(WindowAdapter): # @Override def windowClosing(self, event): endCondition.acquire() endCondition.notifyAll() endCondition.release() class Runnable(Runnable): def __init__(self, runFunction): self._runFunction = runFunction def run(self): self._runFunction() SwingUtilities.invokeLater(Runnable(Example)) endCondition = threading.Condition() endCondition.acquire() endCondition.wait() endCondition.release() ----------------------------------------------- end of revised sample -------------------------------------- Thanks to the help provided here I've created a JFrame to allow me more advanced user interaction and a custom control GUI. I only have one issue at this point, once the items runing in doInBackground (BgTask SwingWorker), you can not gracefully stop stop the script. I get the following error: java.lang.InterruptedException: sleep interrupted which I assume happens due to me trying to interrupt the 'wait' command. I tried to add a try/except to catch the exception, but it doesn't seem to work. Also when I try to use the CTRL+ALT+c hot key it stops the program and makes my JFrame and also the IDE unresponsive. I'm using Windows 7 64bit, I'm using SikulixIDE 1.1.0 CODE: from javax.swing import JButton, JFrame, JTextField, JPanel from java.lang import Runnable, InterruptedException from java.util.concurrent import ExecutionException from javax.swing import SwingWorker, SwingUtilities from java.lang import * from java.awt.event import ActionListener, WindowAdapter import threading class BgTask(SwingWorker): def __init__(self, gui): self.gui = gui SwingWorker.__init__(self) def doInBackground(self): try: click("1463505602802.png") #Random icon on my desktop that is visible wait(5) click("1463514867811.png") #Random icon on my desktop that is visible except InterruptedException: print "***Automation Stuff Should End***" def done(self): try: self.get() except ExecutionException, e: raise SystemExit, e.getCause() # print e.getCause() class Example: def _setButtonStates(self, started): self.stopBtn.enabled = started self.startBtn.enabled = not started def stopSomething(self, event): self.bgTask.cancel(True) self.bgTask = None self._setButtonStates(started=False) def doSomething(self,event): self.bgTask = BgTask(self) self.bgTask.execute() self._setButtonStates(started=True) def __init__(self): frame = JFrame("Gamma Automated Testing") frame.setSize(200, 150) frame.addWindowListener(Adapter()) frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) pnl=JPanel() frame.add(pnl) self.textfield1 = JTextField('', 15) pnl.add(self.textfield1) self.textfield2 = JTextField('', 15) pnl.add(self.textfield2) self.startBtn = JButton('Start Automation', actionPerformed=self.doSomething) self.stopBtn = JButton('Stop', actionPerformed=self.stopSomething) pnl.add(self.startBtn) pnl.add(self.stopBtn) self.stopBtn.enabled = False frame.pack() frame.setVisible(True) endCondition = threading.Condition() class Adapter(WindowAdapter): def windowClosing(self, event): endCondition.acquire() endCondition.notifyAll() endCondition.release() class Runnable(Runnable): def __init__(self, runFunction): self._runFunction = runFunction def run(self): self._runFunction() if __name__ == '__main__': SwingUtilities.invokeLater(Runnable(Example)) endCondition.acquire() # Example() endCondition.wait() endCondition.release() -- You received this question notification because your team Sikuli Drivers is an answer contact for Sikuli. _______________________________________________ Mailing list: https://launchpad.net/~sikuli-driver Post to : [email protected] Unsubscribe : https://launchpad.net/~sikuli-driver More help : https://help.launchpad.net/ListHelp

