Csound Csound-dev Csound-tekno Search About

[Csnd] pyhton and widget operations

Date2012-03-26 09:22
FromTarmo Johannes
Subject[Csnd] pyhton and widget operations

[warning: long mail]

 

Hello,

 

After two tough weeks of rehearsals, concerts and almost two hours of premières I have now again some time for hobby minutes with csound :)

 

I have done some work with the methods that enable to interact with widgets from python console, script or operate them from an instrument in running csd with pyrun or similar opcodes on the fly.

 

I believe it adds a lot of flexibility to the user interface side of working with csound. If you can, and have time, please try out and report if some things work oddly.

 

Please have a look to http://www.incontri.hmtm-hannover.de/fileadmin/www.incontri/Csound_Conference/Cabrera.pdf

as the main reference.

 

Some main changes:

 

1) now the widgets can be created automatically. If user sets the channel name as the third parameter in a widget creation function, the dialog widow will not pop open (and vice versa - if not to set it, all the necessary widget parameters can be inserted in the dialog window). The syntax is now:

 

createNewLabel(x = 0, y = 0, channel = "", index = -1)

 

( Before there was no channel parameter)

 

If not to set any of the parameters, the widget will be created on the current position, properties dialog will be opened and the current document is used.

 

All other widget creation methods are similar, see the link above

 

All these functions return uuid (string) of the widget.

 

 

Let's say you want to create 10 knobs for amplitudes of 10 first partials and according labels. You can execute in python scratchpad:

 

for no in range(0,10):

q.createNewKnob(100*no,5,"partial"+str(no) )

q.createNewLabel(100*no+5,90,"Amplitude "+str(no) )

 

 

2) And later all the properties of the widgets can be changed with

 

setWidgetProperty(widgetid, property, value, index= -1)

 

'widgetid' can be now either the channel name of the widget (more practical when typing to console) OR the uuid of the widget. The latter is more safe since two different widgets can have same channel name (like a slider and a display ). Thus in the previous example it would have been wiser to store the uuids of the widgets right away:

 

knobs = []

labels = []

 

for no in range(0,10):

knobs.append(q.createNewKnob(100*no,5,"partial"+str(no) ) )

labels.append(q.createNewLabel(100*no+10,90,"Amplitude "+str(no) ) )

 

 

To list all possible properties there is now a new function listWidgetProperties(widgetid, index = -1) that returns list of all properties of the widget.

 

Like typing

q.listWidgetProperties("partial0")

 

returns:

 

(u'QCS_x', u'QCS_y', u'QCS_uuid', u'QCS_visible', u'QCS_midichan', u'QCS_midicc', u'QCS_minimum', u'QCS_maximum', u'QCS_value', u'QCS_mode', u'QCS_mouseControl', u'QCS_mouseControlAct', u'QCS_resolution', u'QCS_randomizable', u'QCS_randomizableGroup', u'QCS_width', u'QCS_height', u'QCS_objectName')

 

These are most typical properties to all widgets and all of them can be tweaked.

 

To get a value of a certain property use

 

getWidgetProperty(widgetid, property, index= -1)

 

for example to move first knob down you can do:

 

q.setWidgetProperty( "partial0", "QCS_y", q.getWidgetProperty("partial0","QCS_y")+200 )

 

 

Let's say you now want to modify the maximum of each knob so that the higher partials would have smaller absolute range but the knob operations would be the same ( like max-s 1, 0.9, 0.8 etc) you can do:

 

for a in range(0,10):

q.setWidgetProperty(knobs[a],"QCS_maximum",1-a/10.0)

 

3) delete and recreate the widgets if you need

The destroyWidget(widgetid) is now functional. So you can remove all your labels of the preceding example with:

 

for l in labels:

q.destroyWidget(l)

 

There is also now a new function

 

q.getWidgetUuids(index = -1)

 

that lists uuids of all widgets

 

so you can remove all your widgets with

 

for w in q.getWidgetUuids():

q.destroyWidget(w)

 

 

4) create open and run "slave" csds

 

to load and run a csd there is function

 

loadDocument(name, runNow = false)

 

that has now the second parameter (boolean) runNow. If set to True, the csd will be run immediately as well.

 

It can be useful if one script or "master" csd generates a new csd (or score).

To ceate or put together a new csd there is also a bunch of useful functions:

 

setCsd(text, index = -1);

setFullText(text, index = -1)

setOrc(text, index = -1)

setSco(text, index = -1)

setWidgetsText(text, index = -1)

setPresetsText(text, index = -1)

setOptionsText(text, index = -1)

 

 

and similar get-functions

like

getCsd(index = -1) etc.

 

So you can put together a new csd for example taking orchestra from one open document, score from other (or generate it), make string manipulations to pre-existing templates, add widgets from third one etc.

 

And all that can be done also from a running csd too. I think for people working with algoritmic composition and using python for generating scores it all is very helpful.

 

naturally, for all that CsoundQt must be compiled with PythonQt support.

 

greetings,

tarmo

 

 

to play csd you can use

q.play(inde)