Popsicle is a groundbreaking project designed to extend the accessibility of JUCE by seamlessly integrating it with Python. Leveraging the power of pybind11, Popsicle offers a Pythonic interface to the JUCE framework. This integration allows developers to utilize JUCE in a manner similar to using Qt with PySide, offering a simplified yet robust approach.
In order to use popsicle is necessary to install the wheels from pypi.
pip3 install popsicle
To make sure everything is setup correctly, execute the following command:
python3 -c "import popsicle as juce; print(juce.SystemStats.getJUCEVersion())"
Which should print something like:
JUCE v7.0.9
Now you are ready to rock !
Let's grab a more convoluted example:
import popsicle as juce
el = juce.XmlElement("TEST")
el.setAttribute("property1", "100")
el.setAttribute("property2", "hallo")
el.setAttribute("property3", "1")
os = juce.MemoryOutputStream()
el.writeTo(os)
print(os.toString())
Which invoked should print:
<?xml version="1.0" encoding="UTF-8"?>
<TEST property1="100" property2="hallo" property3="1"/>
Now we would like to start a proper JUCE application with the Message Thread running and all the JUCE bell and whistles, but let's start with having our first JUCEApplication subclass:
import popsicle as juce
class MyFirstPopsicleApp(juce.JUCEApplication):
def __init__(self):
juce.JUCEApplication.__init__(self)
def getApplicationName(self):
return "My First Popsicle App"
def getApplicationVersion(self):
return "1.0"
def initialise(self, commandLineParameters):
print("We were called with:", commandLineParameters)
juce.MessageManager.callAsync(lambda: self.systemRequestedQuit())
def shutdown(self):
print("We were told to shutdown")
Now that we have our application, we need to tell just to use it, let's add this at the end of the file:
At this point, after saving the file (called first_app.py or whatever it suit best), when executed like this:
python3 first_app.py 1 2 3 "test"
Will start and immediately quit, producing this output:
We were called with: 1 2 3 test
We were told to shutdown
In order to show something on screen, we need to build a window with an empty component into it and show it.
import popsicle as juce
class MyFirstPopsicleComponent(juce.Component):
def __init__(self):
juce.Component.__init__(self)
self.setSize(600, 400)
self.setVisible(True)
def paint(self, g):
g.fillAll(juce.Colours.red)
class MyFirstPopsicleWindow(juce.DocumentWindow):
component = None
def __init__(self):
juce.DocumentWindow.__init__(
self,
juce.JUCEApplication.getInstance().getApplicationName(),
juce.Desktop.getInstance().getDefaultLookAndFeel()
.findColour(juce.ResizableWindow.backgroundColourId),
juce.DocumentWindow.allButtons,
True)
self.component = MyFirstPopsicleComponent()
self.setResizable(True, True)
self.setContentNonOwned(self.component, True)
self.centreWithSize(self.component.getWidth(), self.component.getHeight() + self.getTitleBarHeight())
self.setVisible(True)
def __del__(self):
self.clearContentComponent()
if self.component:
self.component.setVisible(False)
del self.component
def closeButtonPressed(self):
juce.JUCEApplication.getInstance().systemRequestedQuit()
Then let's add it to the application:
class MyFirstPopsicleApp(juce.JUCEApplication):
window = None
def __init__(self):
juce.JUCEApplication.__init__(self)
def getApplicationName(self):
return "My First Popsicle App"
def getApplicationVersion(self):
return "1.0"
def initialise(self, commandLineParameters):
self.window = MyFirstPopsicleWindow()
juce.MessageManager.callAsync(lambda: juce.Process.makeForegroundProcess())
def shutdown(self):
if self.window:
del self.window
At this point launching the app will show a window with a red component inside. Great progress !