Contents

Abstract

One of the most important concepts in Plasma is that of the "DataEngine". DataEngines are used to deliver data from somewhere, often from an internet service for example, to your applet. In this tutorial we will discuss DataEngines, what they are, and how to use them from your Plasma applet.

What are DataEngines?

As already mentioned, DataEngines are objects which serve to deliver some kind of data to one or more Plasma applets. Plasma supports many different DataEngines out of the box which deliver all kinds of varied information about things like the state of the machine, e.g. CPU usage, memory usage, position of the mouse pointer; to things such as the current weather report, current time or the latest comic from the internet. DataEngines are used to supply the raw data which an applet displays. Separating the part of the code that fetches data from the part which displays the data, means that one DataEngine can be reused by many applets, regardless of which language the DataEngine or applet is written in. It also makes it easy for people to display the same data using different applets which may tuned towards different uses or screen form factors.

Exploring DataEngines

Plasma comes with a handy tool called plasmaengineexplorer which lists all of the available DataEngines and can be used to examine them to see what kind of data and fields they send. plasmaengineexplorer can be started directly from the shell.
plasmaengineexplorer
Select the "time" in the pulldown list and then click on "Request". This will fetch the list of data sources which the "time" DataEngine makes available.

The "time" DataEngine periodically publishes the current time for many different timezones. The first timezone in the list ("/etc/localtime") is special and simply refers to the current local time on the computer without referring to any specific timezone. If you open the "/etc/localtime" node in the tree you can see which data fields the "time" DataEngine provides. The most important fields are "Time" and "Date". The plasmaengineexplorer also lists what data type the field is, e.g. a QString, QTime or QDate. This information is needed when hooking up a DataEngine to your applet.

Explore some of the other DataEngines in the list. Perhaps it will give you some good ideas for new and interesting applets.

Connecting to a DataEngine

The Python clock code is a good example of how to connect to the "time" DateEngine. You can view the
main.py code here online. Let's take a look at how the Python clock works.

The code to connect to the "time" DataEngine is in the clock's connectToEngine() method, shown below.

defconnectToEngine(self):self.timeEngine=self.dataEngine("time")ifself.showSecondHand:self.timeEngine.connectSource(self.currentTimezone,self,500)else:self.timeEngine.connectSource(self.currentTimezone,self,6000,Plasma.AlignToMinute)</code>Thismethodiscalledfromtheclock's <tt>init()</tt> method. It first calls the <tt>dateEngine()</tt> method on the <tt>plasmascript.Applet</tt> class to get a reference to the "time" DataEngine.The<tt>connectSource()</tt>methodontheDataEnginebindsittothisapplet.Thefirstparameteristhe"DataSource"name.Thiscorrespondstothe"DataSouce"columnin<tt>plasmaengineexplorer</tt>.Forthe"time"DataEngine,itselectswhichtimezoneyouwantthetimefor.Thenextparameteriswherethedatashouldbesent.Inthiscaseitisquitesimple,justsendthedatatothisapplet.Thenumberisthe"polling interval"inmilliseconds.Thisishowoftenthedatashouldbeupdated.Dependingonhowoftentheclockneedstoupdateitsdisplay,itcallsthe<tt>connectSource()</tt>methodwitheither500or6000millisecondsasthepollinginterval.<tt>Plasma.AlignToMinute</tt>indicatestoPlasmawhethertheupdatesshouldbesyncronisedtothesystemclock.Whenmanyappletssyncronisethesameway,thenPlasmacanhandlethedataupdatesforalloftheappletsinlargebatchesinsteadofmanysmallbatches.ThisisimportantonmobiledeviceswhichthrottletheCPUdowntosavebatterypower.Itismoreenergyefficientforthesedevicesifupdatesaredoneinbigbatchesinsteadofmanysmallbatches.Dataisinjectedintotheappletviathe<tt>dataUpdate()</tt>method.<syntaxhighlightlang="python">@pyqtSignature("dataUpdated(const QString &, const Plasma::DataEngine::Data &)")defdataUpdated(self,sourceName,data):self.time=data[QString("Time")].toTime()ifself.time.minute()==self.lastTimeSeen.minute()and \
self.time.second()==self.lastTimeSeen.second():# avoid unnecessary repaintsreturnself.lastTimeSeen=self.timeself.update()</code>The<tt>dataUpdated()</tt>methodtakesthenormalPython<tt>self</tt>parameterinfirstplace,thenthenameofthedatasource(<tt>sourceName</tt>)whichcalled<tt>dataUpdated()</tt>,andthenthedataitself.Thebig<tt>@pyqtSignature()</tt>linejustbefore<tt>dataUpdated()</tt>isaPythondecoratorwhichmarksthisPythonmethodashaving<tt>constQString&,constPlasma::DataEngine::Data&</tt>asitsC++methodsignature.ThisisneededsothatQtcanfindthecorrectmethodonourappletwhendataissent.Thecodejustignoresthe<tt>sourceName</tt>parameterbecauseitknowsthatthedatamustbefromthe"time"DataEngine,andjustconcentratesonthedata.The<tt>sourceName</tt>parameterbecomesimportantwhenyouhavemultipleDataEnginesattachedtothesameapplet.ThedataisdeliveredasaPython<tt>dict</tt>mapping<tt>QString</tt>keysto<tt>QVariant</tt>objectvalues.Whenlookingupthe"Time"keyyouneedtobecarefultousea<tt>QString</tt>asakeyandnotjustanormalPythonstring.Noticehowthecodealsoextractsa<tt>QTime</tt>objectfromthe<tt>QVariant</tt>usingthe<tt>toTime()</tt>method.Nextthe<tt>dataUpdated()</tt>methodhassomecodetomakesurethattheclock's display is only updated if really necessary, followed by the code to actually update the time and redraw the display.==Conclusion==AsyoucanseeDataEnginesareagreatwayofdeliveringdatatoappletswhichcanalsobeeasilyreusedbydifferentapplets.ConnectingaDataEnginetoyourappletisasimplematteroffetchingthedataengineitself,connectinguptothewanteddatasourceandthenacceptingtheprocessingthedatainyourown<tt>dataUpdated()</tt>method.