📜 ⬆️ ⬇️

Another plasmoid creation guide: configuration, events and notifications


Dr.Konqi, we are friends with him, I often see him%)

Instead of the preface


Hello!
On Habré already wrote about the fact that all the plasmoids need to port to QML / JS, but I still continue to mock at the CPP corpse and write plasma widgets on the pros. But maybe not everything is so bad,% username%?

For a simpler example of writing a plasmoid in C ++, you can refer to this article. In this article we will try to add a few features (in ascending order) to the naked widget — the configuration interface, processing of some events and notifications.
If anyone is interested - continued below.

Widget idea


Since the task for me was exclusively educational and self-educational, the idea of ​​the widget is simple: take and fork the Oblique Strategies widget for GNOME. Thus, in our widget will be:

Components


Widget

Heder
#ifndef OBLIKUESTRATEGIES_H #define OBLIKUESTRATEGIES_H #include <Plasma/Applet> #include <Plasma/Label> #include <ui_configwindow.h> class QGraphicsLinearLayout; class oblikuestrategies : public Plasma::Applet { Q_OBJECT public: oblikuestrategies(QObject *parent, const QVariantList &args); ~oblikuestrategies(); int setMessagesText(); void init(); public slots: int autoUpdateEvent(); int sendNotification(QString eventId, int num); int updateEvent(); void mousePressEvent(QGraphicsSceneMouseEvent *event); // for configuration interface int setAutoUpdate(); void configAccepted(); void configChanged(); protected: void createConfigurationInterface(KConfigDialog *parent); private: // ui Plasma::Label *main_label; Plasma::Label *info_label; QTimer *timer; // variables bool autoUpdate_bool, notify_bool; int autoUpdate_int, edition, fontSize, fontWeight; QString fontFamily, fontColor, fontStyle; QStringList formatLine, copyright; QList<QStringList> mess; // configuration interface Ui::ConfigWindow uiConfig; }; K_EXPORT_PLASMA_APPLET(oblikue-strategies, oblikuestrategies) #endif /* OBLIKUESTRATEGIES_H */ 

This will be a kind of "card". The essence of K_EXPORT_PLASMA_APPLET is described in the above article (this is the only fundamentally important thing in the hider). We connect the original libraries, declare the class and destructor
 #include "oblikue-strategies.h" #include <QGraphicsLinearLayout> #include <plasma/theme.h> oblikuestrategies::oblikuestrategies(QObject *parent, const QVariantList &args) : Plasma::Applet(parent, args) { setBackgroundHints(DefaultBackground); setHasConfigurationInterface(true); } oblikuestrategies::~oblikuestrategies() { delete info_label; delete main_label; delete timer; } 

nothing particularly interesting. I note only that we have here established that the applet has a configuration interface. The essence of the variables will be clear just below. Next, we collect the initialization function:
 void oblikuestrategies::init() { if (setMessagesText() != 0) return; // generate ui // layout QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this); layout->setOrientation(Qt::Vertical); // label layout->addStretch(1); main_label = new Plasma::Label(this); main_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); main_label->setToolTip(qApp->translate("tooltip", "Click here to update message")); layout->addItem(main_label); layout->addStretch(1); // copyright label info_label = new Plasma::Label(this); layout->addItem(info_label); } 

The int setMessagesText () function clogs the copyright variables and the actual text of the cards ( mess ), in the process creates a list of two formatLine elements. Then we create a Layout, there are two labels on it - one for text, the other for copyright - and we throw stretch for a beautiful look. Next, go to the configuration interface.
Configuration

Draw a mold. Let it be like this:

Now fasten the function. Read config:
 void oblikuestrategies::configChanged() { KConfigGroup cg = config(); edition = cg.readEntry("edition", 1); fontFamily = cg.readEntry("font_family", "Terminus"); ... } 

I’ll draw your attention to how variables are read. The readEntry method has two arguments - the first variable name in the configuration file (in the depth of the hamster plasma-desktop-appletrc ), the second - the default value. Settings recorded using KConfigGroup will be saved in the file specified above. I will add that this function will be automatically called if the widget settings have been changed.
Do not forget to write the config:
 void oblikuestrategies::configAccepted() { KConfigGroup cg = config(); cg.writeEntry("edition", uiConfig.comboBox_edition->currentIndex()+1); cg.writeEntry("font_family", uiConfig.fontComboBox_font->currentFont().family()); ... } 

Similar to reading. The writeEntry method also has 2 arguments - the name and where to get the values. Now we fasten the interface itself:
 void oblikuestrategies::createConfigurationInterface(KConfigDialog *parent) { QWidget *configwin = new QWidget; uiConfig.setupUi(configwin); uiConfig.comboBox_edition->setCurrentIndex(edition-1); ... parent->addPage(configwin, i18n("Oblikue Strategies"), Applet::icon()); connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted())); } 

Declared an interface, set values ​​(variables are already read in init () by calling the configChanged () method). Then they added an interface to the window (the addPage method is the first argument, the second is the third icon). And tied the button with saving settings. Next fasten events.
Event handling

Suppose we have some method that is responsible for updating the text. Call it int updateEvent () (returns the number of the message that was called). Attach the processing of a mouse click:
 void oblikuestrategies::mousePressEvent(QGraphicsSceneMouseEvent *event) { // mouse click event if (event->buttons() == Qt::LeftButton) updateEvent(); } 

If you double-click, you need to inherit from mouseDoubleClickEvent and, obviously, check for a button is not needed. Now add autoupdate. First we add a timer declaration to the init () method:
 ... // timer timer = new QTimer(this); timer->setSingleShot(false); ... 

Set it to “reusable” use ( setSingleShot (false) ). Next, we screw off and on the timer in the configChanged () method:
  if (autoUpdate_bool == true) { disconnect(timer, SIGNAL(timeout()), this, SLOT(autoUpdateEvent())); timer->stop(); } //   ... if (autoUpdate_bool == true) { connect(timer, SIGNAL(timeout()), this, SLOT(autoUpdateEvent())); timer->start(autoUpdate_int * MSEC_IN_MIN); } 

Just in case: the start () method has an argument period in ms. Add an auto-update feature:
 int oblikuestrategies::autoUpdateEvent() { // auto update text int num = updateEvent(); if (notify_bool == true) if (sendNotification(QString("newMessage"), num) != 0) return 1; return 0; } 

This is where we needed the value returned by the updateEvent () method. This method causes the text to be updated, then, if set to notify_bool == true, calls the method that sends notifications to KDE.
Notifications

First, create the plasma_applet_oblikue-strategies.notifyrc file
 [Global] IconName=oblikue-strategies Name=Oblikue Strategies Comment=Oblikue Strategies [Event/newMessage] Name=New message Comment=There is auto updated message in widget Action=Popup 

The first is general settings, you can leave them without comments. Next comes the listing of events and what they are. Now back to the source. One single method:
 int oblikuestrategies::sendNotification(QString eventId, int num) { // send notification KNotification *notification = new KNotification(eventId); notification->setComponentData(KComponentData("plasma_applet_oblikue-strategies")); notification->setTitle(QString(i18n("Oblikue Strategies"))); notification->setText(mess[edition-1][num]); notification->sendEvent(); delete notification; return 0; } 

eventId is actually our event. In the setComponentData method , specify the name of the applet (so as not to be confused and to simplify). We put the signature, the text and send the message to the system.
Assembly

ls -1 sources
 CMakeLists.txt configwindow.ui oblikue-strategies.cpp oblikue-strategies.h oblikue-strategies.png plasma-applet-oblikue-strategies.desktop plasma_applet_oblikue-strategies.notifyrc 

CMakeLists.txt
 project (plasma_applet_oblikue-strategies) find_package (KDE4 REQUIRED) include (KDE4Defaults) add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES}) set (PLUGIN_NAME ${PROJECT_NAME}) file (GLOB PROJECT_DESKTOP *.desktop) file (GLOB PROJECT_ICON *.png) file (GLOB PROJECT_NOTIFY *.notifyrc) file (GLOB PROJECT_SOURCE *.cpp) file (GLOB PROJECT_UI *.ui) kde4_add_ui_files (PROJECT_SOURCE ${PROJECT_UI}) kde4_add_plugin (${PLUGIN_NAME} ${PROJECT_SOURCE}) target_link_libraries (${PLUGIN_NAME} ${KDE4_PLASMA_LIBS} ${KDE4_KDEUI_LIBS}) # install install (TARGETS ${PLUGIN_NAME} DESTINATION ${PLUGIN_INSTALL_DIR}) install (FILES ${PROJECT_DESKTOP} DESTINATION ${SERVICES_INSTALL_DIR}) install (FILES ${PROJECT_ICON} DESTINATION ${ICON_INSTALL_DIR}) install (FILES ${PROJECT_NOTIFY} DESTINATION ${DATA_INSTALL_DIR}/${PLUGIN_NAME}) 

The file is not quite correct (from the point of view of the human factor, for example), but universal (change only the name of the project to the one you need). From differences from regular build files, call kde4_add_ui_files to create a configuration interface. And setting the file with notifications.

P.S


Sources of this disgrace.
What happened:

According to the materials

Thanks for attention!

')

Source: https://habr.com/ru/post/192698/


All Articles