I’m having difficulty getting Runtime.getRuntime().exec(cmd) to return print() calls from a py5 file. The Processing console output should look like the Terminal output, but is instead very scant and I can’t find any other technique to get a more complete input stream from the py5 app. There are several steps involved to run the demo below and demonstrate the problem:
- Install py5 on your system if you haven’t already. Instructions are here: https://py5coding.org/content/install.html I used the miniconda technique but you could also use venv. You should then have the py5-run-sketch executable on your system shown below (macOS) and cmdStr should point to it.
- The py5 file source code is shown below; save it with the name “Arrows.py”.
- Processing source code also follows. You will need to change the cmdStr and filePath to reflect your system.
- Run the Processing code and give it a few seconds to launch the py5 app. Click on the up and down arrows a few times and then stop the thread by clicking on the default Processing window.
- Compare what you see in your console output with what you should see in Terminal by running ‘cmdStr’ ‘filePath’ at the prompt. Terminal output on my system is also shown below if you want to skip this step.
Thanks in advance for any insight into improving the console output.
Processing source code:
//https://docs.oracle.com/javase/9/docs/api/java/lang/Process.html
//https://py5coding.org/content/install.html
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
Process process;
// *** Change these for your system *** //
String cmdStr = "/opt/miniconda3/bin/py5-run-sketch";
String filePath = "/Users/xxxxx/py5_code/Arrows.py";
void execAction() {
try {
String[] cmd = {cmdStr, filePath};
process = Runtime.getRuntime().exec(cmd);
BufferedReader stdIn = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader stdErr = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String s = "";
while ((s = stdIn.readLine()) != null) {
println(s);
}
String s1 = "";
while ((s1 = stdErr.readLine()) != null) {
println(s1);
}
}
catch (IOException e) {
println("Error: ", e);
}
}
void setup() {
size(250, 150);
surface.setTitle("exec demo");
thread("execAction");
fill(0);
textSize(18);
text("Click here to stop thread.", 20, 20);
}
void draw() {
}
void mousePressed() {
println("mouse pressed.");
process.destroy();
}
py5 source code - save to file named ‘Arrows.py’:
# Uses Imported mode for py5
from controlP5 import ControlP5
this = get_current_sketch()
def drawUpArrow():
upArrw = create_graphics(20,20)
upArrw.begin_draw()
upArrw.background(255)
upArrw.fill(0,255,0)
upArrw.triangle(10,2,2,18,18,18)
upArrw.end_draw()
return upArrw
def drawDownArrow():
dwnArrw = create_graphics(20,20)
dwnArrw.begin_draw()
dwnArrw.background(255)
dwnArrw.fill(0,255,0)
dwnArrw.triangle(2,2,18,2,10,18)
dwnArrw.end_draw()
return dwnArrw
def settings():
size(200,150)
def setup():
global up,dwn,cp5
print("Hello py5 world!!")
window_title("Click on Arrows")
cp5 = ControlP5(this)
upArrw = drawUpArrow()
up = cp5.addButton("up").setId(2).setPosition(90,40).setSize(20,20)
up.setImage(upArrw)
dwnArrw = drawDownArrow()
dwn = cp5.addButton("dwn").setId(1).setPosition(90,60).setSize(20,20)
dwn.setImage(dwnArrw)
def mouse_pressed(e):
if(up.isPressed()):
print("up arrow was pressed.")
if(dwn.isPressed()):
print("down arrow was pressed.")
py5-run-sketch exe:
Console output:
Terminal output. Should see this in Processing console output: