QSystemTrayIcon使用,dock和工具栏上icon点击

该文讲述了如何在Qt环境下,针对Mac操作系统,使用Swizzling技术替换系统方法来监听和处理Dock按钮的点击事件。通过`QSystemTrayIcon`与条件编译指令,实现了不同平台下(尤其是Mac)的特定功能,如在Mac上点击Dock图标时调用自定义方法显示主窗口。
1. 在.cpp中引入头
#include <QSystemTrayIcon>
#ifdef Q_OS_MAC
#include <objc/objc.h>
#include <objc/message.h>
void setupDockClickEvent(); // mac端点击dock用到的方法
bool applicationShouldHandleReopen(id self,SEL _cmd,...);
#endif
2. Swizzling在mac端替换系统方法,监控mac端dock按钮点击
#ifdef Q_OS_MAC
bool applicationShouldHandleReopen(id self,SEL _cmd, ...)
{
    // 点击dock按钮时调用方法
    action_showMain();
    return false;
}
#endif

#ifdef Q_OS_MAC
void setupDockClickEvent()
{

    Class cls = objc_getClass("NSApplication");
    id appInstance = objc_msgSend(cls, sel_registerName("sharedApplication"));

    if(appInstance != nullptr)
    {
        id appDelegate = objc_msgSend(appInstance, sel_registerName("delegate"));
        Class delClass = objc_msgSend(appDelegate,  sel_registerName("class"));

        SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
        if (class_getInstanceMethod(delClass, shouldHandle))
        {

            // 使用Swizzling黑魔法替换 applicationShouldHandleReopen:hasVisibleWindows: 系统方法
            if (class_replaceMethod(delClass, shouldHandle,  reinterpret_cast<IMP>(applicationShouldHandleReopen), "B@:"))
                qDebug() << "方法替换成功";
            else
                qDebug() << "方法替换失败";
        }
        else
        {
            if (class_addMethod(delClass, shouldHandle, reinterpret_cast<IMP>(applicationShouldHandleReopen),"B@:"))
                qDebug() << "添加dock点击方法成功";
            else
                qDebug() << "添加dock点击方法成功失败";
        }
    }
}
#endif
3. 添加QSystemTrayIcon
	trayicon = new QSystemTrayIcon(this);
    trayicon->setToolTip("垣连");

#if defined(Q_OS_WIN)
	// 只有windows端添加只有右击菜单,mac端单击就显示这个菜单,与单击展示页面冲突,丑,不加
    trayicon->setIcon(QIcon(":/icon/images/icon.png")); // windows的icon画布正方形
    trayMenu = new TrayIconMenu();
    QAction *main_action = new QAction(tr("打开主屏幕"),this);
    QAction *exit_action = new QAction(tr("退出"),this);

    QObject::connect(main_action,SIGNAL(triggered()),this,SLOT(action_showMain()));
    QObject::connect(exit_action,SIGNAL(triggered()),this,SLOT(action_exit()));

    trayMenu->addAction(exit_action);
    trayMenu->addAction(main_action);

    trayicon->setContextMenu(trayMenu);

#elif defined(Q_OS_MACOS)
    setupDockClickEvent(); // 进行dock方法替换
    trayicon->setIcon(QIcon(":/icon/images/icon_mac.png")); // mac的icon画布长方形,不然会显得icon很大
#endif
	QObject::connect(trayicon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(iconActived(QSystemTrayIcon::ActivationReason)));
    trayicon->show();
4. 点击dock按钮和头部icon将页面展示在最前边
// 打开主页面
void action_showMain()
{
    if (this->isMinimized()) this->showNormal();
    if (this->isHidden()) this->show();
    this->setWindowState(Qt::WindowActive);
    this->raise(); // mac端将窗口放在最前边
    this->activateWindow(); // windows端将窗口放在最前边,两端还不一样

}

// 退出app
void action_exit()
{
    qApp->quit();
}
<think>好的,用户问的是“QSystemTrayIcon如何使用”,我需要详细回答这个问题。首先,我得回忆一下QSystemTrayIcon用法QSystemTrayIconQt中用于在系统托盘显示图标处理交互的类。用户可能想了解如何创建托盘图标、添加菜单、响应点击事件等。 接下来,我应该分步骤说明。首先需要检查系统是否支持系统托盘,因为有些系统可能没有这个功能。然后创建QSystemTrayIcon对象,设置图标提示信息。接着,可能需要关联菜单,处理点击事件,比如单击、双击触发的动作。 然后要考虑代码示例,比如如何初始化,如何设置上下文菜单,连接信号槽。可能还需要提到在应用程序退出时正确清理资源,比如隐藏托盘图标。 用户可能在使用过程中遇到问题,比如图标不显示,或者事件无法触发。这时候需要提醒检查系统支持情况,确保图标资源正确,以及正确使用信号槽机制。 还要考虑不同平台的差异,比如WindowsLinux可能有不同的行为,是否需要特别处理。比如在Linux下可能需要检查是否有托盘管理器运行。 另外,相关问题部分需要列出用户可能进一步询问的问题,比如如何动态更新图标、处理不同事件、跨平台注意事项等。确保这些问题覆盖常见疑问,帮助用户深入理解。 最后,检查回答是否结构清晰,步骤明确,代码示例正确,并且相关问题全面。确保没有遗漏关键点,比如信号槽的连接资源管理。</think>`QSystemTrayIcon` 是 Qt 提供的系统托盘图标管理类,可用于实现应用最小化到托盘、显示通知等功能。以下是完整使用指南: --- ### 基本用法 ```cpp #include <QSystemTrayIcon> #include <QMenu> #include <QAction> // 创建托盘对象并设置图标 QSystemTrayIcon *trayIcon = new QSystemTrayIcon(this); trayIcon->setIcon(QIcon(":/icon/app.ico")); // 设置图标路径 trayIcon->setToolTip("我的应用"); // 设置悬停提示 // 创建右键菜单 QMenu *trayMenu = new QMenu(); QAction *restoreAction = trayMenu->addAction("还原"); QAction *quitAction = trayMenu->addAction("退出"); trayIcon->setContextMenu(trayMenu); // 绑定菜单 // 显示托盘图标 trayIcon->show(); // 信号连接示例 connect(trayIcon, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason){ if (reason == QSystemTrayIcon::DoubleClick) { showNormal(); // 双击托盘图标恢复窗口 } }); connect(restoreAction, &QAction::triggered, this, &MyWindow::showNormal); connect(quitAction, &QAction::triggered, qApp, &QApplication::quit); ``` --- ### 关键功能说明 1. **图标控制** - `setIcon(QIcon)`:支持多种格式(PNG/JPG/ICO) - `setVisible(bool)`:控制图标显示状态 - `setAnimationEnabled(bool)`(Qt6新增):启用动画图标 2. **消息通知** ```cpp trayIcon->showMessage("标题", "这是一条通知", QSystemTrayIcon::Information, 5000); // 支持图标类型:Info/Warning/Critical/NoIcon ``` 3. **事件处理** - 激活事件:通过 `activated` 信号捕获单击/双击/右键等操作 - 消息点击事件:连接 `messageClicked()` 信号 --- ### 注意事项 1. **平台差异** - Windows:原生支持 - Linux:需要系统托盘管理器(如 StatusNotifierItem) - macOS:从 Qt 5.15 开始支持,但功能受限 2. **生命周期管理** - 在 `closeEvent` 中隐藏托盘图标: ```cpp void MyWindow::closeEvent(QCloseEvent *event) { if (trayIcon->isVisible()) { hide(); event->ignore(); // 阻止窗口关闭 } } ``` 3. **资源释放** - 使用 `deleteLater()` 安全释放对象 - 避免在托盘图标显示时直接 `delete` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值