DataEngine and Python2 or As I wrote my widget

    Instead of the foreword


    After sitting a bit in awesome, I decided to return to the more familiar sneakers (KDE4), hung with a lot of necessary and not very goodies. After a while, I decided to remove the ugly self-written karamba widget (SuperKaramba) and replace it with a more elegant and simple plasma widget. The requirements for it were simple: it should be a simple widget on the panel, which would display in the form of text all the basic (or rather, the information I demanded) information. After searching kde-look.org, I found one widget that suited me well enough. However, I needed some additional features that were not implemented in this widget. Also, the author did not provide for the possibility of easily configuring the widget, and to configure it, I had to go into the original script written in JavaScript.
    After several iterations, the settings of the existing widget, due to my lack of any idea about JS, I decided to write my own widget. Of the programming languages, Python2 was chosen, in which I more or less understand. No sooner said than done. Over the evening, I wrote the first version of the widget, which is fully functional. Later, during testing, it was discovered that it has an unpleasant feature to hang during the update. Firstly, this was due to the fact that all fields were updated at the same time. And secondly, and this, perhaps, the most important thing - parsing files with data (among them / proc / stat and a file that contains information about transmitted / received traffic) needs some delay. If you set them to 0.2 seconds, then in the end the widget freezes for almost 0.5 seconds, which is noticeable even with the naked eye.
    Then I made an attempt to rewrite the code by including the DataEngine, which I spied in the original widget. Below we will talk about using this module in Python2.

    The only problem with using this module is the lack of any documentation for it in Python2. There is for cpp with a description of the required parameters in the function (Python doesn’t have this either), and there is a small note in the development tutorialwith a very childish example. Because of this, I had to work blindly in the image and likeness, so something can certainly be done more elegantly and simply. Immediately, before moving on to the descriptive part, I note that my programming skills are not so much more, which also cannot but affect the quality of the code. So, please excuse me if I suddenly do something wrong.
    Also, the purpose of this article does not include a guide for writing plasmoids in Python, for this there are already other articles, for example: one and two .
    So, after a long introduction, let's get started.

    The basics


    You can view the list of available services using the plasmaengineexplorer utility (in ArchLinux it is included in the plasmate package available in the aura). The interface is simple, like a felt boot: We

    selected the required tool (engine) from the drop-down list, a lot of lines appeared that contain information (in Python it is transmitted as a dictionary). It should be noted that, at least in the case of the systemmonitor tool, the variable also has the key ' value ', which contains the information of interest.
    The tool is connected even easier (in the class of the widget itself):
    from PyKDE4.plasma import Plasma
    def connectToEngine(self):
        """function to initializate engine"""
        self.systemmonitor = self.dataEngine("systemmonitor")

    The only option is our DataEngine. However, we have not yet connected to the necessary data, therefore we will not see anything. If we want to find out the average processor load, then the continuation of the function will look like this:
        self.systemmonitor.connectSource("cpu/system/TotalLoad", self, 1000)

    There are three parameters. The first is where we turn to - source (in general, it requires the QString format, although, usually, you can slip a simple string). This is the first column in plasmaengineexplorer . The second parameter is visualization (where the parameter will be sent), we indicate the widget itself. The third parameter is the update interval (int), ms is the time after which we will ask if the information has been updated. In general, everything is already ready, it remains only to add the update function:
    @pyqtSignature("dataUpdated(const QString &, const Plasma::DataEngine::Data &)")
    def dataUpdated(self, sourceName, data):
        """function to refresh data"""
        if (sourceName == "cpu/system/TotalLoad"):
            value = str(round(float(data[QString(u'value')]), 1))
            cpuText = "%5s" % (value)

    cpuText - a string of five characters - for example, '100.0'. A few comments - data (here) is our dictionary, sourceName is source, which is updated (indicated above), data [QString (u'value ')] is the value we are interested in (behind other keys - again, to plasmaengineexplorer ). Voila, the widget is ready, it remains only to display the obtained value and that’s it. I note that updating the text of the widget makes sense directly in this function.

    Few details


    Update

    If you use only DataEngine, you do not need to create a timer, the data will be updated by yourself. Also, it is worth noting that I could not make friends with the powermanager tool (for reading the battery charge) - this was due to the fact that the charge value was not updated by itself (if the power adapter was connected). Accordingly, the initial value was not read until it changed (unless, of course, I understand correctly).

    Simultaneous update

    It may be necessary if you want, for example, to calculate the memory load in%. I honestly admit that I did not manage to do this. However, if I'm not mistaken, I need to dig towards such a combination:
    self.engine.addSource(self.container)
    self.engine.connectAllSources(self, 1000)

    Add sources, and then connect them at once. The problem with the definition of the container (variable type PyKDE4.plasma.Plasma.DataContainer). You can create your own container and fill it with data, but I could not connect it to an existing source. Therefore, in the current version of the widget, the values ​​that are further used are written into variables that are processed by a special function after the timer expires.

    Advantages and disadvantages

    Parallel update of widget elements, lack of delays (data is read right there) and high speed. Also, it is worth noting that DataEngine contains a lot of all sorts of useful things that can be used when writing widgets. Among the drawbacks is the dependence on the presence of a module in the system ( kdebindings-python2 package in the case of ArchLinux).

    Afterword


    Widget sources are available on github or at kde-look.org . In the final version, the widget (if anyone is interested) looks like this (although a fairly flexible configuration is provided):

    I apologize if, in your opinion, the text is very blurry, if desired, it can be squeezed twice.

    Also popular now: