IT Notes

QSystemTrayIcon: Иконка в системном трее для Qt-приложения

Разработаем простую Qt-программу, которая использует иконку в системном трее. Для этого воспользуемся классом QSystemTrayIcon. Приложение будет состоять из двух частей: виджета с одной кнопкой Show message и иконки в системном трее.

Особенности реализации:

  • при щелчке левой кнопкой мыши на иконке в трее виджет будет исчезать/появляться;
  • по нажатию правой кнопкой мыши на иконке в трее появится контекстное меню с пунктом Exit, который завершает работу приложения;
  • при закрытии виджета приложение не будет завершать работу, а лишь перейдет в фоновый режим (восстановить видимость виджета можно щелчком левой кнопкой мыши по иконке в трее).

qsystemtrayicon-demo-thumbnail

Заголовочный файл mainwidget.h:

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>
#include <QSystemTrayIcon>

namespace Ui {
class MainWidget;
}

class MainWidget : public QWidget {
    Q_OBJECT

public:
    explicit MainWidget( QWidget* parent = 0 );
    ~MainWidget();

    void closeEvent( QCloseEvent* event );

private slots:
    void onTrayIconActivated( QSystemTrayIcon::ActivationReason reason );
    void onShowMessageInTray();

private:
    Ui::MainWidget* ui;
    QSystemTrayIcon* m_trayIcon;
};

#endif // MAINWIDGET_H

Указатель на QSystemTrayIcon мы объявляем полем класса главного виджета. Для реагирования на щелчки мышью по иконке в системном трее мы подготовили слот onTrayIconActivated(). Обработчиком щелчка по кнопке на виджете становится слот onShowMessageInTray().

Чтобы приложение не завершало работу при закрытии главного виджета, мы переопределяем обработчик события closeEvent().

Реализация mainwidget.cpp:

#include "mainwidget.h"
#include "ui_mainwidget.h"

#include <QIcon>
#include <QMenu>
#include <QCloseEvent>

MainWidget::MainWidget( QWidget* parent ) :
    QWidget( parent ),
    ui( new Ui::MainWidget ) {
    ui->setupUi( this );

    connect( ui->bnShowMsg, SIGNAL( clicked( bool ) ), SLOT( onShowMessageInTray() ) );

    m_trayIcon = new QSystemTrayIcon( QIcon( ":/images/tray_icon.ico" ), this );
    connect(
        m_trayIcon,
        SIGNAL( activated( QSystemTrayIcon::ActivationReason ) ),
        SLOT( onTrayIconActivated( QSystemTrayIcon::ActivationReason ) )
    );

    QMenu* menu = new QMenu;

    QAction* exitAction = menu->addAction( "Exit" );
    connect( exitAction, SIGNAL( triggered( bool ) ), qApp, SLOT( quit() ) );

    m_trayIcon->setContextMenu( menu );

    m_trayIcon->show();
}

MainWidget::~MainWidget() {
    delete ui;
}

void MainWidget::closeEvent( QCloseEvent* event ) {
    hide();
    event->ignore();
}

void MainWidget::onTrayIconActivated( QSystemTrayIcon::ActivationReason reason ) {
    switch( reason ) {
    case QSystemTrayIcon::Trigger:
        setVisible( !isVisible() );
        break;

    default:
        break;
    }
}

void MainWidget::onShowMessageInTray() {
    m_trayIcon->showMessage( "Message title", "Message text", QSystemTrayIcon::Information );
}

Инициализация иконки в трее осуществляется в конструкторе MainWidget. Она состоит из нескольких частей: установка изображения (tray_icon.ico, помещенного в ресурсы), задание родителя (для избежания утечек памяти), привязка сигнала activated() к слоту-обработчику и добавление контекстного меню.

Оставшаяся часть реализации достаточно тривиальна, поэтому в дополнительных пояснениях не нуждается.

Исходники

 Скачать пример использования QSystemTrayIcon в Qt-приложении

Похожие публикации

Комментарии

Спасибо полезная статья =)

А возможно сделать радио плеер в Qt 4.8 ?

http://doc.qt.io/qt-5/qradiotuner.html

Здравствуйте. Спасибо за комментарий.

Класс QRadioTuner не входит в стандартный комплект Qt 4.8. Если нет зависимостей от сторонних библиотек, то лучше перейти на Qt 5 (имеется практически полная обратная совместимость). Если же есть ограничения на использование именно Qt 4.8, то можно задействовать библиотеки 3-ей стороны.

С наступающим =)

Спасибо =) Всех читателей с наступающим!