QT在 MacOS X上,如何检测点击程序坞中的Dock图标

最近在开发MacOS的qt应用,在做到最小化系统托盘功能时,发现关闭窗口后再次点击程序坞中的Dock图标不能将主界面再显示出来。查询里很多资料,发现是QT自身的问题,没有做相关的点击Dock图标的处理。

于是我参考了国内和国外的这两篇文章

国内:QT 实现Dock应用程序点击 ---Mac OS X_qt点击dock触发事件-CSDN博客

国外:https://stackoverflow.com/questions/15143369/qt-on-os-x-how-to-detect-clicking-the-app-dock-icon

使用他们的代码,编译不过,会报错

cpp 复制代码
error: no matching function for call to 'objc_msgSend' note: candidate function not viable: requires 0 arguments, but 2 were provided

我的环境是qt6.7.2,在qtcreator中开发,还是会报error: no matching function for call to 'objc_msgSend'这个错误。经过一番折腾和问chatgpt,给出的结果是:

于是对代码进行改造

pro的配置不变

cpp 复制代码
macx {
    LIBS += -framework CoreFoundation
    LIBS += -lobjc
    LIBS += -framework AppKit
    DEFINES += OBJC_OLD_DISPATCH_PROTOTYPES
}

代码作以下改动

cpp 复制代码
#ifdef Q_OS_MAC
#include <objc/objc.h>
#include <objc/message.h>
bool applicationShouldHandleReopen(id self,SEL _cmd,...);
#endif
void setupDockClickEvent();
 
 
 
#ifdef Q_OS_MAC
bool applicationShouldHandleReopen(id self,SEL _cmd, ...)
{
    qDebug()<<__FUNCTION__;
 
    // Return NO (false) to suppress the default OS X actions
    return false;
}
#endif
 
void setupDockClickEvent()
{
#ifdef Q_OS_MAC
    Class cls = objc_getClass("NSApplication");

    // 声明 objc_msgSend 的函数指针
    id (*objc_msgSend_id)(id, SEL) = (id(*)(id, SEL))objc_msgSend;
 
    id appInstance = objc_msgSend_id((id)cls, sel_registerName("sharedApplication"));
 
    if(appInstance != nullptr)
    {
        id appDelegate = objc_msgSend_id(appInstance, sel_registerName("delegate"));
        Class delClass = (Class)objc_msgSend_id(appDelegate,  sel_registerName("class"));
 
        SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
        if (class_getInstanceMethod(delClass, shouldHandle))
        {
 
            if (class_replaceMethod(delClass, shouldHandle,  reinterpret_cast<IMP>(applicationShouldHandleReopen), "B@:"))
                qDebug() << "Registered dock click handler (replaced original method)";
            else
                qWarning() << "Failed to replace method for dock click handler";
        }
        else
        {
            if (class_addMethod(delClass, shouldHandle, reinterpret_cast<IMP>(applicationShouldHandleReopen),"B@:"))
                qDebug() << "Registered dock click handler";
            else
                qWarning() << "Failed to register dock click handler";
        }
    }
#endif
}

main.cpp中还是一样

cpp 复制代码
int main(int argc, char *argv[])
{
    setupDockClickEvent();
}

至于国外论坛提到的第二种方法,本人并没有进行尝试,大家可以自行尝试一下

相关推荐
明月(Alioo)4 小时前
机器学习入门,用Lima在macOS免费搭建Docker环境,彻底解决镜像与收费难题!
macos·docker·容器
小江村儿的文杰4 小时前
UE4 Mac构建编译报错 no template named “is_void_v” in namespace “std”
macos·ue4
MonkeyKing_sunyuhua6 小时前
mac怎么安装uv工具
python·macos·uv
猫头虎7 小时前
IDE mac M芯片安装报错:如何解决“InsCode.app 已损坏”,无法打开
ide·vscode·macos·inscode·编辑器·idea·mac
笑尘pyrotechnic8 小时前
push pop 和 present dismiss
macos·ui·ios·objective-c·cocoa
lichong9519 小时前
【混合开发】Android+Webview+VUE播放视频之视频解析工具mediainfo-Macos
android·macos·架构·vue·音视频·api·postman
小妖66612 小时前
mac 安装 nginx
运维·nginx·macos
魔道不误砍柴功12 小时前
Mac 能够连Wife,但是不能上网问题解决
网络·macos·php
daizhe12 小时前
Mac M4环境下基于VMware Fusion虚拟机安装Ubuntu24.04 LTS ARM版
ubuntu·macos
伐尘19 小时前
【mac】如何在 macOS 终端中高效查找文件:五种实用方法
运维·macos