Qt | 创建系统托盘 QSystemTrayIcon

405 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第6天,点击查看活动详情

前言

系统托盘是个特殊区域,通常在桌面的底部。通常系统托盘不会只显示一个小图标,还会对鼠标事件做出反应。大多数的系统托盘中的小图标,在用户用鼠标右击时都会弹出一个菜单以方便用户选择。所以系统托盘会搭配菜单一起使用。

系统托盘

Qt中实现系统托盘的类是QSystemTrayIcon,它为系统托盘中的应用程序提供一个图标。所以我们如果要为我们的应用程序创建系统托盘,直接创建QSystemTrayIcon类就可以了。可以通过setIcon设置托盘的图标;还可以通过setToolTip设置鼠标在上面时显示的提示信息。

    // 最好定义成成员变量
    QSystemTrayIcon m_sysTrayIcon = new QSystemTrayIcon(this);
    QIcon icon = QIcon("image/icon.png");
    m_sysTrayIcon->setIcon(icon);
    m_sysTrayIcon->setToolTip(QString::fromLocal8Bit("我的托盘"));

显示与隐藏

因为我们在创建系统托盘的时候给它设置了父指针,所以当父指针销毁的时候,会自动将我们的系统托盘销毁掉。我们只需要控制它的创建、显示与隐藏就可以了。

m_sysTrayIcon.show();
m_sysTrayIcon.hide();

菜单

系统托盘会搭配菜单一起使用,当我们点击系统托盘时,会显示一个菜单列表,上面会有一些操作项。点击任意一项都会去执行相应的操作。当我们点击桌面或系统托盘以及菜单以外其他区域时,菜单列表会隐藏起来。菜单我们会用到QMenu这个类,菜单中的每一项对应了一个QAction,具体实现如下。

    // 托盘--菜单 打开主面板
    QAction m_openAction = new QAction(QString::fromLocal8Bit("打开主面板"), this);
    connect(m_openAction, SIGNAL(triggered()), this, SLOT(slotTrayIconOpenAction()));
    // 托盘--菜单 退出
    QAction m_exitAction = new QAction(QString::fromLocal8Bit("退出"), this);
    QIcon iconExit = QIcon("image/close.png"); // 设置图标
    m_exitAction->setIcon(iconExit);
    connect(m_exitAction, SIGNAL(triggered()), this, SLOT(slotTrayIconExitAction()));

    // 菜单
    QMenu m_menu = new QMenu(QApplication::desktop()); 
    m_menu->addAction(m_openAction);
    m_menu->addAction(m_exitAction);
    m_menu->setStyleSheet(
                "QMenu{background:white;border:1px solid lightgray;width:132px;height:96px;}"
                "QMenu::icon{position:absolute;left:15px;}"
                "QMenu::item{padding-left:21px;height:32px;width:130px;}"
                "QMenu::item:hover{background:#EFF5FF;}"
                "QMenu::item:selected{background:#EFF5FF;}"); // 设置样式
                
    // 将菜单设置给系统托盘            
    m_sysTrayIcon->setContextMenu(m_menu);

响应活动

QSystemTrayIcon有一个active信号,当用户激活系统托盘图标时会发出此信号。参数Reason指定了激活原因。Trigger表示单击系统托盘条目,当用户单击系统托盘条目时,可以实现显示主窗体,并将主窗体设置为活动窗口。

connect(m_sysTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
            this, SLOT(slotSysTrayIconActivated(QSystemTrayIcon::ActivationReason)));
void MainWidget::slotSysTrayIconActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch(reason)
    {
    case QSystemTrayIcon::Trigger:
        this->show();
        this->setWindowState(Qt::WindowActive);
        activateWindow();
        break;
    default:
        break;
    }
}
  • setWindowState: 设置窗口状态为windowState。窗口状态是Qt::WindowState: Qt:: windowminimal, Qt::WindowMaximized, Qt::WindowFullScreen和Qt::WindowActive的或组合。WindowActive表示该窗口是活动窗口,即它具有键盘焦点。
  • activateWindow:将包含此小部件的顶级小部件设置为活动窗口。 活动窗口是具有键盘输入焦点的可见顶层窗口。