시스템 트레이 아이콘 예제

시스템 트레이 아이콘 예제는 데스크톱 환경의 시스템 트레이에 메뉴 및 팝업 메시지가 있는 아이콘을 추가하는 방법을 보여줍니다.

시스템 트레이 아이콘 스크린샷

최신 운영 체제는 일반적으로 바탕화면에 시스템 트레이 또는 알림 영역이라는 특수 영역을 제공하여 장기 실행 애플리케이션이 아이콘과 짧은 메시지를 표시할 수 있도록 합니다.

이 예는 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, restorequit 동작이 포함된 메뉴를 제공합니다. 메인 애플리케이션 창을 최대화하거나 최소화하는 등 에디터의 모양이 변경될 때마다 트레이 아이콘의 메뉴를 업데이트하기 위해 QWidget::setVisible() 함수를 다시 구현합니다.

마지막으로 QWidgetcloseEvent() 함수를 다시 구현하여 사용자가 아이콘의 컨텍스트 메뉴에서 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 열거형은 풍선 메시지가 표시될 때 표시되는 아이콘을 설명합니다. 그런 다음 QSystemTrayIconshowMessage() 함수를 호출하여 밀리초 단위로 지정된 시간 동안 제목, 본문 및 아이콘이 포함된 메시지를 표시합니다.

macOS 사용자 참고: QSystemTrayIcon::showMessage()가 메시지를 표시하려면 Growl 알림 시스템이 설치되어 있어야 합니다.

QSystemTrayIcon 또한 사용자가 showMessage()에 표시된 메시지를 클릭할 때 발생하는 해당 messageClicked() 신호가 있습니다.

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 는 현재 스타일에 따라 짧은 메시지, 아이콘 및 버튼이 배치된 모달 대화 상자를 제공합니다. 네 가지 심각도 수준을 지원합니다: "질문", "정보", "경고" 및 "심각". 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

© 2025 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.