このページでは

システムトレイアイコンの例

「システムトレイアイコン」の例では、デスクトップ環境のシステムトレイに、メニューやポップアップメッセージ付きのアイコンを追加する方法を示しています。

ネットワークの問題に関するシステムトレイのポップアップ

システムトレイアイコンのスクリーンショット

最近のオペレーティングシステムでは通常、デスクトップ上に「システムトレイ」または「通知領域」と呼ばれる特別な領域が用意されており、長時間実行されるアプリケーションはそこにアイコンや短いメッセージを表示することができます。

この例は、メインのアプリケーションウィンドウ(つまり、システムトレイアイコン用のエディタ)と関連するアイコンを提供する、Window という単一のクラスで構成されています。

ポップアップのタイトル、表示時間、メッセージなど、さまざまな設定を編集するためのシステムトレイエディタ

このエディタを使用すると、ユーザーは好みのアイコンを選択できるほか、バルーンメッセージの種類や表示時間を設定できます。また、メッセージのタイトルや本文を編集することも可能です。最後に、このエディタには、システムトレイにアイコンを実際に表示するかどうかを制御するチェックボックスが用意されています。

ウィンドウクラスの定義

Window クラスはQWidget を継承しています:

class Window : public QDialog
{
    Q_OBJECT

public:
    Window();

    void setVisible(bool visible) override;

protected:
    void closeEvent(QCloseEvent *event) override;

private slots:
    void setIcon(int index);
    void iconActivated(QSystemTrayIcon::ActivationReason reason);
    void showMessage();
    void messageClicked();

private:
    void createIconGroupBox();
    void createMessageGroupBox();
    void createActions();
    void createTrayIcon();

    QGroupBox *iconGroupBox;
    QLabel *iconLabel;
    QComboBox *iconComboBox;
    QCheckBox *showIconCheckBox;

    QGroupBox *messageGroupBox;
    QLabel *typeLabel;
    QLabel *durationLabel;
    QLabel *durationWarningLabel;
    QLabel *titleLabel;
    QLabel *bodyLabel;
    QComboBox *typeComboBox;
    QSpinBox *durationSpinBox;
    QLineEdit *titleEdit;
    QTextEdit *bodyEdit;
    QPushButton *showMessageButton;

    QAction *minimizeAction;
    QAction *maximizeAction;
    QAction *restoreAction;
    QAction *quitAction;

    QSystemTrayIcon *trayIcon;
    QMenu *trayIconMenu;
};

ユーザーの操作に応答するために、いくつかのプライベートスロットを実装しています。その他のプライベート関数は、コンストラクタを簡略化するために提供されている単なる便宜上の関数です。

トレイアイコンは、QSystemTrayIcon クラスのインスタンスです。ユーザーのデスクトップにシステムトレイが存在するかどうかを確認するには、静的関数QSystemTrayIcon::isSystemTrayAvailable()を呼び出します。このアイコンに関連して、一般的なminimize 、maximize 、restore 、quit といったアクションを含むメニューを提供しています。QWidget::setVisible() 関数を再実装し、メインアプリケーションウィンドウの最大化や最小化など、エディタの表示状態が変更されるたびに、トレイアイコンのメニューを更新するようにしました。

最後に、QWidget のcloseEvent()関数を再実装し、エディタウィンドウを閉じる際に、ユーザーがアイコンのコンテキストメニューから「Quit 」を選択するまで、プログラムがシステムトレイで実行され続けることをユーザーに通知できるようにします。

ウィンドウクラスの実装

エディタウィジェットを構築する際、実際のシステムトレイアイコンを作成する前に、まず各種エディタ要素を作成します:

Window::Window()
{
    createIconGroupBox();
    createMessageGroupBox();

    iconLabel->setMinimumWidth(durationLabel->sizeHint().width());

    createActions();
    createTrayIcon();

    connect(showMessageButton, &QAbstractButton::clicked, this, &Window::showMessage);
    connect(showIconCheckBox, &QAbstractButton::toggled, trayIcon, &QSystemTrayIcon::setVisible);
    connect(iconComboBox, &QComboBox::currentIndexChanged,
            this, &Window::setIcon);
    connect(trayIcon, &QSystemTrayIcon::messageClicked, this, &Window::messageClicked);
    connect(trayIcon, &QSystemTrayIcon::activated, this, &Window::iconActivated);

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(iconGroupBox);
    mainLayout->addWidget(messageGroupBox);
    setLayout(mainLayout);

    iconComboBox->setCurrentIndex(1);
    trayIcon->show();

    setWindowTitle(tr("Systray"));
    resize(400, 300);
}

エディタの入力ウィジェット(システムトレイアイコンを含む)の大部分をアプリケーションのプライベートスロットに接続することで、アプリケーションがユーザー入力に応答するようにします。ただし、可視性チェックボックスについては注意が必要です。そのtoggled()シグナルは、代わりにアイコンの setVisible()関数に接続されています。

void Window::setIcon(int index)
{
    QIcon icon = iconComboBox->itemIcon(index);
    trayIcon->setIcon(icon);
    setWindowIcon(icon);

    trayIcon->setToolTip(iconComboBox->itemText(index));
}

setIcon() スロットは、アイコンコンボボックスの現在のインデックスが変更されるたびに、つまりユーザーがエディタ内で別のアイコンを選択するたびにトリガーされます。また、ユーザーがマウスの左ボタンでトレイアイコンをアクティブにした際にも呼び出され、アイコンのactivated()シグナルをトリガーすることにも注意してください。このシグナルについては後ほど詳しく説明します。

QSystemTrayIcon::setIcon() 関数は、実際のシステムトレイアイコンを保持するicon プロパティを設定します。Windows では、システムトレイアイコンのサイズは 16x16 です。X11 では、推奨サイズは 22x22 です。アイコンは必要に応じて適切なサイズにスケーリングされます。

なお、X11 では、システムトレイ仕様の制限により、アイコンの透明部分へのマウスクリックがシステムトレイに伝播されます。この挙動が許容できない場合は、透明部分のないアイコンを使用することをお勧めします。

void Window::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason) {
    case QSystemTrayIcon::Trigger:
    case QSystemTrayIcon::DoubleClick:
        iconComboBox->setCurrentIndex((iconComboBox->currentIndex() + 1) % iconComboBox->count());
        break;
    case QSystemTrayIcon::MiddleClick:
        showMessage();
        break;
    default:
        ;
    }
}

ユーザーがシステムトレイアイコンをアクティブにするたびに、そのアイコンはトリガーとなった理由をパラメータとして渡して、activated()シグナルを発行します。QSystemTrayIcon は、アイコンがどのようにアクティブ化されたかを記述するためのActivationReason 列挙型を提供しています。

コンストラクタ内で、アイコンのactivated()シグナルを、カスタムiconActivated() スロットに接続しました。ユーザーがマウスの左ボタンでアイコンをクリックした場合、この関数はアイコンコンボボックスの現在のインデックスをインクリメントしてアイコン画像を変更し、前述のようにsetIcon() スロットをトリガーします。 ユーザーがマウスの中ボタンでアイコンをアクティブにした場合、カスタムスロットshowMessage() が呼び出されます:

void Window::showMessage()
{
    showIconCheckBox->setChecked(true);
    int selectedIcon = typeComboBox->itemData(typeComboBox->currentIndex()).toInt();
    QSystemTrayIcon::MessageIcon msgIcon = QSystemTrayIcon::MessageIcon(selectedIcon);

    if (selectedIcon == -1) { // custom icon
        QIcon icon(iconComboBox->itemIcon(iconComboBox->currentIndex()));
        trayIcon->showMessage(titleEdit->text(), bodyEdit->toPlainText(), icon,
                          durationSpinBox->value() * 1000);
    } else {
        trayIcon->showMessage(titleEdit->text(), bodyEdit->toPlainText(), msgIcon,
                          durationSpinBox->value() * 1000);
    }
}

showMessage()スロットがトリガーされると、まず現在選択されているメッセージタイプに応じてメッセージアイコンを取得します。QSystemTrayIcon::MessageIcon 列挙型は、バルーンメッセージが表示された際に表示されるアイコンを定義しています。その後、QSystemTrayIcon のshowMessage()関数を呼び出し、指定されたミリ秒間、タイトル、本文、およびアイコンを含むメッセージを表示します。

macOSユーザーへの注意:QSystemTrayIcon::showMessage()がメッセージを表示するには、Growl通知システムがインストールされている必要があります。

QSystemTrayIcon また、対応するmessageClicked()シグナルもあり、これはユーザーがshowMessage()によって表示されたメッセージをクリックしたときに発火します。

void Window::messageClicked()
{
    QMessageBox::information(nullptr, tr("Systray"),
                             tr("Sorry, I already gave what help I could.\n"
                                "Maybe you should try asking a human?"));
}

コンストラクタでは、messageClicked() シグナルを、QMessageBox クラスを使用して単にメッセージを表示するカスタムのmessageClicked() スロットに接続しました。

QMessageBox は、短いメッセージ、アイコン、および現在のスタイルに応じて配置されたボタンを備えたモーダルダイアログを提供します。4つの重大度レベル(「質問」、「情報」、「警告」、「重大」)をサポートしています。 Qtでメッセージボックスを表示する最も簡単な方法は、関連する静的関数(例:QMessageBox::information ())のいずれかを呼び出すことです。

前述したように、QWidget の仮想関数のいくつかを再実装しています:

void Window::setVisible(bool visible)
{
    minimizeAction->setEnabled(visible);
    maximizeAction->setEnabled(!isMaximized());
    restoreAction->setEnabled(isMaximized() || !visible);
    QDialog::setVisible(visible);
}

QWidget::setVisible() 関数の再実装では、メインアプリケーションウィンドウの最大化や最小化など、エディタの表示状態が変更されるたびに、基底クラスの実装を呼び出す前に、トレイアイコンのメニューを更新するようにしています。

void Window::closeEvent(QCloseEvent *event)
{
    if (!event->spontaneous() || !isVisible())
        return;
    if (trayIcon->isVisible()) {
        QMessageBox::information(this, tr("Systray"),
                                 tr("The program will keep running in the "
                                    "system tray. To terminate the program, "
                                    "choose <b>Quit</b> in the context menu "
                                    "of the system tray entry."));
        hide();
        event->ignore();
    }
}

ウィジェットの閉じるイベントを受け取るために、QWidget::closeEvent() イベントハンドラを再実装し、ユーザーがエディタウィンドウを閉じようとした際に上記のメッセージを表示するようにしました。 ユーザーが実際にアプリケーションを終了しようとしている場合、つまり、メニューバーやトレイアイコンのコンテキストメニューから「終了」を選択した場合、あるいは macOS で Command+Q ショートカットを押した場合などは、メッセージの表示や終了イベントの処理を回避する必要があります。

前述の関数やスロットに加え、コンストラクタを簡略化するための便利な関数をいくつか実装しました:createIconGroupBox() 、createMessageGroupBox() 、createActions() 、およびcreateTrayIcon() です。詳細については、desktop/systray/window.cpp ファイルを参照してください。

サンプルプロジェクト @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.