Notice: This forum has been recovered from an old backup, so some content, links, and dates may be outdated. The forum is currently read-only while we restore sign-in and registration functionality. Details

If you find this forum valuable and would like to help keep it online, donations to help cover hosting and domain costs are greatly appreciated, but never expected. You can support the forum through Buy Me a Coffee or Ko-fi. Thank you for helping preserve the EventGhost community.

wxPython / wxProcess?

If you have a question or need help, this is the place to be.
Post Reply
thug
Plugin Developer
Posts: 64
Joined: Sat Jul 22, 2006 2:37 pm
Location: Australia

wxPython / wxProcess?

Post by thug »

How do I use the wxProcess command?

Is it available and can it be used in a plugin?

I want to capture a processes stdin & stdout (I start) via the GetInputStream & GetOutputStream, but to do that I need to use wxExecute (can't find that either) but first i need to use the wxProcess command.

I have tried using it like this :-

Code: Select all


from wxPython.wx import *
import wxPython

class MyPlayer(eg.PluginClass):
    def __init__(self):
      self.AddAction(self.PlayFile)

    class PlayFile(eg.ActionWithStringParameter):
        description = "Start playing a file."
        def __call__(self, data):
            print "PlayFile: '", data, "'"
            print "Process: ", wxProcess(self)
            

But i get this error on the "wxProcess(self)" line every time i call PlayFile from python script.

Code: Select all

Process: Traceback (most recent call last):
  Python script "5", line 2, in ?
    eg.plugins.MyPlayer.PlayFile(eg.event.payload)
  Python script "plugins/MyPlayer/__init__.py", line 152, in __call__
Error in Action: "Python Script"
Traceback (most recent call last):
  File "C:\Program Files\EventGhost\eg\TreeItems\ActionItem.py", line 298, in Execute
  File "eg/CorePlugins/EventGhost\PythonScript.py", line 330, in __call__
ValueError: invalid literal for int(): plugins/MyPlayer/__init__.py
Help!!!
User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Post by Bitmonster »

1. I never tried wxProcess myself. For such problems I have used "popen", but this might be far to complex for your task, so wxProcess is worth a try.
2. The errorlog shows, you have tried to make a plugin inside a PythonScript action.. This won't work. You have to create a real plugin, with a folder in plugins/, an __info__.py and an __init__.py
3. I would suggest to always use the new "import wx" and not "from wxPython.wx import *". I never use it that way and py2exe that is used to make the complete distribution might not add the other ways to the library.
4. "wxProcess(self)" will not work (or because of 3. better say "wx.Process") because you have "self" as parameter. The documentation about it says:
wxProcess(wxEvtHandler * parent = NULL, int id = -1)
or
wxProcess(int flags)
So you have to supply a wx-eventhandler or a special integer flag that is either wxPROCESS_DEFAULT or wxPROCESS_REDIRECT. And that is why it reports "invalid literal for int()", as you haven't supplied an integer but "self" as parameter.
User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Post by Bitmonster »

Well, I did some research on wx.Process and it seems not to be well supported in wxPython.
The reason is simple: Python already has more advanced modules to handle this. The most general is the "subprocess" module.

But capturing and handling pipes is always a pain in the ass, especially if you have to control stdin and stdout simultaneous.
One approach I have used lately was posted here:
http://aspn.activestate.com/ASPN/Cookbo ... ipe/440554
thug
Plugin Developer
Posts: 64
Joined: Sat Jul 22, 2006 2:37 pm
Location: Australia

Post by thug »

hmmm..

Changed the code to (prior error ( last post ) was from a call to the plugin, full __init__.py follows):-

Code: Select all
























import eg

from wxPython.wx import *  # need this for wxPROCESS_DEFAULT
import wx
import wxPython
import wxPython.wx

class MyPlayer(eg.PluginClass):
    def __init__(self):
      self.AddAction(self.PlayFile)
      
    class PlayFile(eg.ActionWithStringParameter):
        description = "Start playing a file."
        def __call__(self, data):
            print "PlayFile: '", data, "'"
            print ("wx:", wxPROCESS_DEFAULT)

            print "Process: ", wxProcess(wxPROCESS_DEFAULT)


            
            return 1
and still get the exact same error in EG (sorry to repeat myself)

Code: Select all

Python Script
PlayFile: ' ['9'] '
('wx:', 0)
Process: Traceback (most recent call last):
  Python script "8", line 2, in ?
    eg.plugins.MyPlayer.PlayFile(eg.event.payload)
  Python script "plugins/MyPlayer/__init__.py", line 40, in __call__
Error in Action: "Python Script"
Traceback (most recent call last):
  File "C:\Program Files\EventGhost\eg\TreeItems\ActionItem.py", line 298, in Execute
  File "eg/CorePlugins/EventGhost\PythonScript.py", line 330, in __call__
ValueError: invalid literal for int(): plugins/MyPlayer/__init__.py
all four methods of wxprocess give the exact same error (above).

Not sure why it's doing this... :?

yeah, i don't want this to get to complex. :)
User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Post by Bitmonster »

It seems, that wx.Process only handles the first kind of parameters, so you have to supply a wx.EvtHandler like this:
myEventHandler = wx.EventHandler()
process = wx.Process(myEventHandler)

But this will have many other problems, as wx.Execute can only be used from the MainThread and your plugin will run in another thread. Therfor I suggest to use subprocess.Popen.

BTW: You can use wxPROCESS_DEFAULT with the new style simply like this:
wx.PROCESS_DEFAULT
So there is no need to import wxPython and especially not the "from import *". Simply use "import wx" everywhere.
thug
Plugin Developer
Posts: 64
Joined: Sat Jul 22, 2006 2:37 pm
Location: Australia

Post by thug »

First hitch with Popen....

using the source from the link (above post) issuing :-

Code: Select all

import eg
import os
import subprocess
import errno
import time
import sys
i get

Code: Select all

12:57:55 PM Python Script
12:57:55 PM Traceback (most recent call last):
12:57:55 PM   Python script "19", line 3, in ?
12:57:55 PM     import subprocess
12:57:55 PM ImportError: No module named subprocess
where is subprocess? :cry:
same error when it's in a plugin too ( 2x :cry: )
User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Post by Bitmonster »

Ok, there were a couple of problems:
1. I only have used subprocess inside my development version, that runs from source. The EXE had no subprocess module installed, so actually there was no subprocess.
2. There was a bug in reporting tracebacks from PythonScripts. This confused me a bit, as it has thrown another exception when an exception was raised inside a script. This was also the case in your first example with wx.Process, so my assumption about the integer-problem was faulty.
3. To use subprocess.Popen under a program that runs through py2exe (as EventGhost does, when it's installed as an EXE) needs some special tricks, that are described here:
http://starship.python.net/crew/theller ... teractions

So I have uploaded a new version (0.3.3 build 650) that includes subprocess and the traceback-bugfix. If you want to use the example from the link above you have to change:
a = Popen(shell, stdin=PIPE, stdout=PIPE)
into
a = Popen(shell, stdin=PIPE, stdout=PIPE, stderr=file('nul', 'a'))

and change:
if __name__ == '__main__':
into
if 1:
as PythonScripts don't run as "__main__" modules.
Post Reply