Python control of a wxpython GUI app

I've written a wxpython application which is mainly intended to be
controlled via the UI. However I would like to also make the app
controlable via python. I'm looking for any examples/articles on how
to go about this?

At the moment my app is a single script and I'd like to keep it that
way if possible from simplicity of distribution.

You can do something like this:

if __name__ == '__main__':
    createUI()

where createUI is a function that creates the wx App and so on. The
conditional will only evaluate to True if the module was the one "run"
by Python directly; if it is imported from another module then the
conditional will be False.

-Chris

···

On Wed, Mar 28, 2012 at 12:36 PM, Jonno <jonnojohnson@gmail.com> wrote:

I've written a wxpython application which is mainly intended to be
controlled via the UI. However I would like to also make the app
controlable via python. I'm looking for any examples/articles on how
to go about this?

Thanks Chris. I guess my main question though is how to interact with
the app once I launch the Mainloop(). Or is that even possible?

···

On Wed, Mar 28, 2012 at 2:44 PM, Chris Weisiger <cweisiger@msg.ucsf.edu> wrote:

You can do something like this:

if __name__ == '__main__':
createUI()

where createUI is a function that creates the wx App and so on. The
conditional will only evaluate to True if the module was the one "run"
by Python directly; if it is imported from another module then the
conditional will be False.

-Chris

On Wed, Mar 28, 2012 at 2:05 PM, Jonno > Thanks Chris. I guess my main
question though is how to interact with

the app once I launch the Mainloop(). Or is that even possible?

Once the mainloop is started, the easiest way to interact with the app
is via events. It's really easy to create an event with wx.CallAfter()
This can even be done from a different thread (most wx calls have to
be run in the same thread). wx.CAllAfter(fun) puts an event on teh
event stack that then calls fun(): the function you pass in. So it can
be used to run virtually anything.

But there needs to be a way for the user to tell the app he/she wants
to do something -- do you have something in mind other than the GUI?

perhaps what you want is an embedded terminal -- see:

wx.py.shell

and/or google for other options.

A little more description of your use case might help, if this isn't
what you were asking.

-Chris

···

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

My app is quite complex and I'm trying to figure out the general
principles so perhaps it would be simpler to work with an example.
Take this calculator example: CalculatorDemo - wxPyWiki
Let's say I want to launch the calculator (gui and all) from another
script and then give it some inputs and then tell it to calculate the
sum of the inputs and then display the result in the UI. How would one
do that?

···

On Wed, Mar 28, 2012 at 4:16 PM, Chris Barker <chris.barker@noaa.gov> wrote:

On Wed, Mar 28, 2012 at 2:05 PM, Jonno > Thanks Chris. I guess my main
question though is how to interact with

the app once I launch the Mainloop(). Or is that even possible?

Once the mainloop is started, the easiest way to interact with the app
is via events. It's really easy to create an event with wx.CallAfter()
This can even be done from a different thread (most wx calls have to
be run in the same thread). wx.CAllAfter(fun) puts an event on teh
event stack that then calls fun(): the function you pass in. So it can
be used to run virtually anything.

But there needs to be a way for the user to tell the app he/she wants
to do something -- do you have something in mind other than the GUI?

perhaps what you want is an embedded terminal -- see:

wx.py.shell

and/or google for other options.

A little more description of your use case might help, if this isn't
what you were asking.

-Chris

I’m a newbie in this regard, but it sounds like you may want to use pubsub. (Note that pubsub is now part of the standard wxPython distribution.) FWIW,

DG

···

On Wed, Mar 28, 2012 at 2:31 PM, Jonno jonnojohnson@gmail.com wrote:

On Wed, Mar 28, 2012 at 4:16 PM, Chris Barker chris.barker@noaa.gov wrote:

On Wed, Mar 28, 2012 at 2:05 PM, Jonno > Thanks Chris. I guess my main

question though is how to interact with

the app once I launch the Mainloop(). Or is that even possible?

Once the mainloop is started, the easiest way to interact with the app

is via events. It’s really easy to create an event with wx.CallAfter()

This can even be done from a different thread (most wx calls have to

be run in the same thread). wx.CAllAfter(fun) puts an event on teh

event stack that then calls fun(): the function you pass in. So it can

be used to run virtually anything.

But there needs to be a way for the user to tell the app he/she wants

to do something – do you have something in mind other than the GUI?

perhaps what you want is an embedded terminal – see:

wx.py.shell

and/or google for other options.

A little more description of your use case might help, if this isn’t

what you were asking.

-Chris

My app is quite complex and I’m trying to figure out the general

principles so perhaps it would be simpler to work with an example.

Take this calculator example: http://wiki.wxpython.org/CalculatorDemo

Let’s say I want to launch the calculator (gui and all) from another

script and then give it some inputs and then tell it to calculate the

sum of the inputs and then display the result in the UI. How would one

do that?

To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com

or visit http://groups.google.com/group/wxPython-users?hl=en


Note my address change and please update your address books. Thanks!

When you say "another script" do you mean from a separate process or all in the same program? If the former then an easy way to do it is to implement something like an XML-RPC or RPyC server in your GUI application that runs in a background thread. The other task can then call the methods of that server object as if they were local objects and you just need to implement the code on the other end that will safely pass the request from the server thread to the GUI thread (like by sending events, using wx.CallAfter, etc.)

If you meant all within the same program then at a high level it is really almost the same, just simpler and different at the implementation level. At the high level you still need to provide a way to pass messages or call methods in the GUI from different parts of your application. One way is a message passing system like the already mentioned pubsub. Or you can just ensure that the part of the code that needs to call the function has the access it needs to do so, for example, a reference to the object that has the method to be called, and then just call it. (Taking care about multi-threaded safety if needed of course.)

···

On 3/28/12 2:31 PM, Jonno wrote:

My app is quite complex and I'm trying to figure out the general
principles so perhaps it would be simpler to work with an example.
Take this calculator example: CalculatorDemo - wxPyWiki
Let's say I want to launch the calculator (gui and all) from another
script and then give it some inputs and then tell it to calculate the
sum of the inputs and then display the result in the UI. How would one
do that?

--
Robin Dunn
Software Craftsman

On Wed, Mar 28, 2012 at 2:31 PM, Jonno

My app is quite complex and I'm trying to figure out the general
principles so perhaps it would be simpler to work with an example.
Take this calculator example: CalculatorDemo - wxPyWiki
Let's say I want to launch the calculator (gui and all) from another
script and then give it some inputs and then tell it to calculate the
sum of the inputs and then display the result in the UI. How would one
do that?

when you say -- "launch from another script" do you mean as a separate
process? If so, then you need some inter-application communication
method -- there are a number.

Or can you modify the original app, and launch it from within another
script in the same process? (maybe a different thread...) if so, then
pubsub and/or wx.CallAfter will do it:

···

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

On Wed, Mar 28, 2012 at 2:31 PM, Jonno

Take this calculator example: CalculatorDemo - wxPyWiki
Let's say I want to launch the calculator (gui and all) from another
script and then give it some inputs and then tell it to calculate the
sum of the inputs and then display the result in the UI. How would one
do that?

got curious, so I did a bit more:

first, that demo brings up a dialog with ShowModal() which kind of
complicates things, as that crates its own event loop. so I
re-factored it to use a regular frame.

Then the app had no hooks to have it calculate -- sending key strokes
seemed to be overkill (and difficult to do cross-platform) -- so I
added a "ComputeExpression" mehtod, that sets an expression, and calls
compute (I needed to factor out the compute method, too...)

Anyway, with a now "drivable" GUII app, I wrote a script that starts
up the app, then starts up a new thread to do stuff in, then starts
the mailoop of the app.

as the secondary thread does its thing -- it uses wx.CallAfter to call
the "ComputeExpression" method on the Calculator.

Note that in this case, calling that method directly worked, but
that's not reliable with multi-threading.

This was kind of fun -- even though maybe not what you were looking for.

See enclosed. (start the CalculatorDriver.py) script to run.

-Chris

CalculatorDemo.py (2.69 KB)

CalculatorDriver.py (853 Bytes)

···

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Thanks Chris. I'll take a look at this and see if I can make sense of
it. Looks like I need to study a bit.

···

On Wed, Mar 28, 2012 at 6:44 PM, Chris Barker <chris.barker@noaa.gov> wrote:

On Wed, Mar 28, 2012 at 2:31 PM, Jonno

Take this calculator example: CalculatorDemo - wxPyWiki
Let's say I want to launch the calculator (gui and all) from another
script and then give it some inputs and then tell it to calculate the
sum of the inputs and then display the result in the UI. How would one
do that?

got curious, so I did a bit more:

first, that demo brings up a dialog with ShowModal() which kind of
complicates things, as that crates its own event loop. so I
re-factored it to use a regular frame.

Then the app had no hooks to have it calculate -- sending key strokes
seemed to be overkill (and difficult to do cross-platform) -- so I
added a "ComputeExpression" mehtod, that sets an expression, and calls
compute (I needed to factor out the compute method, too...)

Anyway, with a now "drivable" GUII app, I wrote a script that starts
up the app, then starts up a new thread to do stuff in, then starts
the mailoop of the app.

as the secondary thread does its thing -- it uses wx.CallAfter to call
the "ComputeExpression" method on the Calculator.

Note that in this case, calling that method directly worked, but
that's not reliable with multi-threading.

This was kind of fun -- even though maybe not what you were looking for.

See enclosed. (start the CalculatorDriver.py) script to run.

-Chris

Since this was so much fun, I did a bit more.

This version puts the GUI in a secondary thread, leaving the main
thread active. In this case, you can then use the command line to send
expressions to the calculator to evaluate.

Try starting up CalculatorDemoDriver.py on a command line.

-Chris

CalculatorDemo.py (3.18 KB)

CalculatorDemoDriver.py (1.33 KB)

···

On Thu, Mar 29, 2012 at 7:47 AM, Jonno <jonnojohnson@gmail.com> wrote:

On Wed, Mar 28, 2012 at 6:44 PM, Chris Barker <chris.barker@noaa.gov> wrote:

On Wed, Mar 28, 2012 at 2:31 PM, Jonno

Take this calculator example: CalculatorDemo - wxPyWiki
Let's say I want to launch the calculator (gui and all) from another
script and then give it some inputs and then tell it to calculate the
sum of the inputs and then display the result in the UI. How would one
do that?

got curious, so I did a bit more:

first, that demo brings up a dialog with ShowModal() which kind of
complicates things, as that crates its own event loop. so I
re-factored it to use a regular frame.

Then the app had no hooks to have it calculate -- sending key strokes
seemed to be overkill (and difficult to do cross-platform) -- so I
added a "ComputeExpression" mehtod, that sets an expression, and calls
compute (I needed to factor out the compute method, too...)

Anyway, with a now "drivable" GUII app, I wrote a script that starts
up the app, then starts up a new thread to do stuff in, then starts
the mailoop of the app.

as the secondary thread does its thing -- it uses wx.CallAfter to call
the "ComputeExpression" method on the Calculator.

Note that in this case, calling that method directly worked, but
that's not reliable with multi-threading.

This was kind of fun -- even though maybe not what you were looking for.

See enclosed. (start the CalculatorDriver.py) script to run.

-Chris

Thanks Chris. I'll take a look at this and see if I can make sense of
it. Looks like I need to study a bit.

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

you can also interface with autoit through python which will allow you to actually perform GUI clicks and text entry , etc

something like

from win32com.client import Dispatch

import pythoncom

pythoncom.CoInitialize()

Auto = Dispatch(“AutoItX3.Control”) #Download autoit v3 (http://www.autoitscript.com/cgi-bin/getfile.pl?autoit3/autoit-v3-setup.exe)

while not Auto.WinExists(title, “”):

print “Missing Window:”, title

smartsleep(0.25)

Auto.WinActivate(title)

Auto.WinWaitActive(title)

smartsleep(wait)

Auto.Send(cmd)

pythoncom.CoUninitialize()

···

On Thursday, 29 March 2012 10:50:29 UTC-7, Chris Barker wrote:

Since this was so much fun, I did a bit more.
This version puts the GUI in a secondary thread, leaving the main
thread active. In this case, you can then use the command line to send
expressions to the calculator to evaluate.

Try starting up CalculatorDemoDriver.py on a command line.

-Chris

On Thu, Mar 29, 2012 at 7:47 AM, Jonno jonnojohnson@gmail.com wrote:

On Wed, Mar 28, 2012 at 6:44 PM, Chris Barker chris.barker@noaa.gov wrote:

On Wed, Mar 28, 2012 at 2:31 PM, Jonno

Take this calculator example: http://wiki.wxpython.org/CalculatorDemo
Let’s say I want to launch the calculator (gui and all) from another
script and then give it some inputs and then tell it to calculate the
sum of the inputs and then display the result in the UI. How would one
do that?

got curious, so I did a bit more:

first, that demo brings up a dialog with ShowModal() which kind of
complicates things, as that crates its own event loop. so I
re-factored it to use a regular frame.

Then the app had no hooks to have it calculate – sending key strokes
seemed to be overkill (and difficult to do cross-platform) – so I
added a “ComputeExpression” mehtod, that sets an expression, and calls
compute (I needed to factor out the compute method, too…)

Anyway, with a now “drivable” GUII app, I wrote a script that starts
up the app, then starts up a new thread to do stuff in, then starts
the mailoop of the app.

as the secondary thread does its thing – it uses wx.CallAfter to call
the “ComputeExpression” method on the Calculator.

Note that in this case, calling that method directly worked, but
that’s not reliable with multi-threading.

This was kind of fun – even though maybe not what you were looking for.

See enclosed. (start the CalculatorDriver.py) script to run.

-Chris

Thanks Chris. I’ll take a look at this and see if I can make sense of
it. Looks like I need to study a bit.


To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Ok I think I'm getting there. I'm now able to send commands to the app
while the GUI is running and it reflects the changes. However I have a
function in my code which runs when a button is pushed. How do I
"push" this button remotely. I need to pass an event to it right?

···

On Thu, Mar 29, 2012 at 12:50 PM, Chris Barker <chris.barker@noaa.gov> wrote:

got curious, so I did a bit more:

first, that demo brings up a dialog with ShowModal() which kind of
complicates things, as that crates its own event loop. so I
re-factored it to use a regular frame.

Then the app had no hooks to have it calculate -- sending key strokes
seemed to be overkill (and difficult to do cross-platform) -- so I
added a "ComputeExpression" mehtod, that sets an expression, and calls
compute (I needed to factor out the compute method, too...)

Anyway, with a now "drivable" GUII app, I wrote a script that starts
up the app, then starts up a new thread to do stuff in, then starts
the mailoop of the app.

as the secondary thread does its thing -- it uses wx.CallAfter to call
the "ComputeExpression" method on the Calculator.

Note that in this case, calling that method directly worked, but
that's not reliable with multi-threading.

This was kind of fun -- even though maybe not what you were looking for.

See enclosed. (start the CalculatorDriver.py) script to run.

-Chris

Thanks Chris. I'll take a look at this and see if I can make sense of
it. Looks like I need to study a bit.

That's one way, but as wx uses native widgets, you don't have easy
access to system events (at least not in a platform-independent way).

unless you REALLY need the user to see the visual effect of the button
being pushed, why not just call the function that EVT_BUTTON is bound
to?

IF the event handler expect an event object, you can simply do:

def on_button(self, event=None):
   ...

and if it actually does something with that event (or the object it
came from) then refactor the code so that the GUI-independent part can
be used by itself -- that's what I did in CalculatorDemo.py

-Chris

···

On Fri, Mar 30, 2012 at 2:02 PM, Jonno <jonnojohnson@gmail.com> wrote:

However I have a
function in my code which runs when a button is pushed. How do I
"push" this button remotely. I need to pass an event to it right?

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov