[Csnd] pyhton and widget operations
Date | 2012-03-26 09:22 |
From | Tarmo 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)
|