解决MacOS下QT无边框最小化失效,最小化后点击Dock图标无法恢复窗口的问题

最近才开始接触MacOS下的QT开发,发现无边框的窗口,最小化无效,而且用其他方法隐藏窗口后,点击底部Dock栏图标,也无法恢复窗口,试国内网上的很多方法,但都是无效的,我的qt版本是5.14.2,所以找到了可以用的方法(国内的mac下qt开发的资料真的太少了,而且mac下的qt真的很坑)。

工程文件pro文件里添加:

macx {
    LIBS += -framework CoreServices
    LIBS += -framework Foundation
    LIBS += -framework CoreFoundation
    LIBS += -framework Carbon
    LIBS += -lobjc
    LIBS += -framework AppKit
    DEFINES += OBJC_OLD_DISPATCH_PROTOTYPES
}

最小化函数里用下面的代码:

NSView* view = (NSView*)window()->winId();
NSWindow* wnd = [view window];
[wnd setStyleMask:[wnd styleMask] | NSWindowStyleMaskMiniaturizable];
showMinimized();
wasMinimized = true;

 

但最小化后,发现点击dock栏图标,无法恢复窗口;

解决方法:

将main.cpp改名main.mm,并在main(int argc, char *argv[])函数前加入下面代码:

#ifdef Q_OS_MAC
#include 
#include 
#include 

bool applicationShouldHandleReopen(id self,SEL _cmd, ...)
{
    qDebug()<<__FUNCTION__;
    return false;
}
void setupDockClickEvent()
{

    Class cls = objc_getClass("NSApplication");

    SEL sharedApplication = sel_registerName("sharedApplication");

    objc_object *appInst = (objc_object*)objc_msgSend((id)cls, sharedApplication);

    if(appInst != nullptr)
    {
        objc_object* delegate = (objc_object*)objc_msgSend((id)appInst,sel_registerName("delegate"));
        objc_object* delegateClass = (objc_object*)objc_msgSend((id)delegate, sel_registerName("class"));

        //constchar* tst = (constchar*)class_getName((Class)delegateClass->isa);
        SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
        bool bTst = class_getInstanceMethod((Class)delegateClass,shouldHandle);
        if(bTst)
        {
            bool test = class_replaceMethod((Class)delegateClass,
                               shouldHandle,
                               //(IMP)dockClickHandler((id)appInst,sharedApplication),
                                            reinterpret_cast(applicationShouldHandleReopen),
                                            "B@:");
            // "B@:" is quite tricky thing called Method Signature which allows to define C function to selector "applicationShouldHandleReopen:hasVisibleWindows:" and dockClickHandler function will be called as if it was written inside objective-c code.

            if(test)
            {
                qDebug("Registration was successful");
            }
            else
            {
                qDebug("Registration was failed");
            }
        }
        else
        {
            bool test = class_addMethod((Class)delegateClass,
                               shouldHandle,
                               //(IMP)dockClickHandler((id)appInst,sharedApplication),
                                        reinterpret_cast(applicationShouldHandleReopen),
                                        "B@:");
            // "B@:" is quite tricky thing called Method Signature which allows to define C function to selector "applicationShouldHandleReopen:hasVisibleWindows:" and dockClickHandler function will be called as if it was written inside objective-c code.

            if(test)
            {
                qDebug("Registration was successful");
            }
            else
            {
                qDebug("Registration was failed");
            }
        }

    }

}
#endif

然后在main(int argc, char *argv[])函数中,在QApplication a(argc, argv);后面加入下面的调用代码:

#ifdef Q_OS_MAC
    setupDockClickEvent();
#endif

然后最小化后,点击Dock图标的事件,就会在applicationShouldHandleReopen函数里 处理了

你可能感兴趣的:(QT,MacOS,qt,macos)