I have a C++ program (that uses Qt), and I want to create a tray notification with a progress bar. I think Qt can show text notifications, but not progress bar - that's KDE-specific. I can't find any example of managing KDE tray notifications in C++. Any advice?
P. S. Here's what I mean:
I was wondering the same thing, and I spent some time investigating. Here are the results:
That progress bar is a special feature of kde that's not linked to libnotify at all. It is provided by a component called kuiserver, and it is meant to display progress of file transfert, though it can be used for other things.
There are two ways
The first way is to talk to kuiserver in the KDE API, and it's by using KUiServerJobTracker with a KJob. I haven't tried myself, but I guess you should subclass KJob, and pass an instance of your subclass to KUiServerJobTracker.
You can also talk directly to the kuiserver through dbus, which is what I tried. I used qdbusviewer
to explore the API provided by kuiserver. I wanted to show an example of interaction with the command-line tool qdbus
, but I couldn't get it to work. If you plan to do this, you probably should use
the QDBus library.
What is interesting to us is the /JobViewServer
path in the org.kde.kuiserver
service. The method we want to call is org.kde.JobViewServer.requestView
, which creates a new dbus path for this job, and returns it. For example, I just called requestView
with dummy arguments, and got ObjectPath: /JobViewServer/JobView_29
in return. In the meantime, a progress indicator has just started rotating in my tray:
I can now use the content of that path. Here, qdbus
worked, so here is the list of the methods:
$ qdbus org.kde.kuiserver /JobViewServer/JobView_29
signal void org.kde.JobViewV2.cancelRequested()
method Q_NOREPLY void org.kde.JobViewV2.clearDescriptionField(uint number)
signal void org.kde.JobViewV2.resumeRequested()
method bool org.kde.JobViewV2.setDescriptionField(uint number, QString name, QString value)
method Q_NOREPLY void org.kde.JobViewV2.setDestUrl(QDBusVariant destUrl)
method Q_NOREPLY void org.kde.JobViewV2.setInfoMessage(QString message)
method Q_NOREPLY void org.kde.JobViewV2.setPercent(uint percent)
method Q_NOREPLY void org.kde.JobViewV2.setProcessedAmount(qulonglong amount, QString unit)
method Q_NOREPLY void org.kde.JobViewV2.setSpeed(qulonglong bytesPerSecond)
method Q_NOREPLY void org.kde.JobViewV2.setSuspended(bool suspended)
method Q_NOREPLY void org.kde.JobViewV2.setTotalAmount(qulonglong amount, QString unit)
signal void org.kde.JobViewV2.suspendRequested()
method Q_NOREPLY void org.kde.JobViewV2.terminate(QString errorMessage)
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name)
method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface_name)
method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QDBusVariant value)
method QString org.freedesktop.DBus.Introspectable.Introspect()
method QString org.freedesktop.DBus.Peer.GetMachineId()
method void org.freedesktop.DBus.Peer.Ping()
I'll let you guess and experiment to find what those do, but here is a small example:
# Give it a name, in case we open the tooltip
qdbus org.kde.kuiserver /JobViewServer/JobView_29 setInfoMessage "Example progress"
# Update the progress
qdbus org.kde.kuiserver /JobViewServer/JobView_29 setPercent 50
# End it
qdbus org.kde.kuiserver /JobViewServer/JobView_29 terminate "Some error message"
You should have enough to create a progress bar in the tray with kde. I hope this'll be useful to you. Anyway, I had fun finding this out (including diving in some kde applications code to find out how the progress notification was done), and I'll probably write something that uses this.
You can use QxtToolTip which is a class in Qxt. It enabales you to show any arbitrary widget as a tooltip. So i think you can create your custom widget and show it using QxtToolTip in the proper position. You can use this static function:
void QxtToolTip::show ( const QPoint & pos, QWidget * tooltip, QWidget * parent = 0, const QRect & rect = QRect() ) [static]
It can be like:
#include <QxtToolTip>
MyCustomWidget widget;
QPoint myPosition(x,y);
QxtToolTip::show ( &myPosition, &widget, parent);
To get in the system tray you want to use KStatusNotifierItem and for the notifications you'll want to take a look at the KNotifications framework.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With