QWidget on Mac OS X not focusing in Qt 5.x

与世无争的帅哥 提交于 2019-11-29 06:31:15

A bit offtopic, but it may be usefull for some users:

My proposal is to create platform-depended code to force raising of window. There are same problem on Windows platform, so I'm using next hack:

    void Utils::forceForegroundWindow( WId winId )
    {
#ifdef Q_OS_WIN
        HWND hWnd = winId;

        if ( ::IsWindow( hWnd ) )
        {
            HWND hCurrWnd;
            int iMyTID;
            int iCurrTID;

            hCurrWnd = ::GetForegroundWindow();
            iMyTID   = ::GetCurrentThreadId();
            iCurrTID = ::GetWindowThreadProcessId( hCurrWnd, 0 );

            ::AttachThreadInput( iMyTID, iCurrTID, TRUE );

            ::ShowWindow( hWnd, SW_SHOWNORMAL );
            ::SetForegroundWindow( hWnd );

            ::AttachThreadInput( iMyTID, iCurrTID, FALSE );
        }

#endif
    }

I still not provide Mac OS compatibility in my project, so this code has no functionality for non-win platforms.

Another idea: you should always keep focused visible window. Try to do one with WA_TranslucentBackground | WA_TransparentForMouseEvents attributes + FramelessWindowHint flag. So your application will never loose focus.

So I managed to fix the problem with platform depended code. I created Focuser class with code in the .mm file and that contained Objective-C code that called Cocoa.

focuser.h

#ifndef FOCUSER_H
#define FOCUSER_H

#include <QWidget>

class Focuser {
  QWidget *widget;
public:
  Focuser(QWidget *);
  void show();
  void focus();
};

#endif // FOCUSER_H

focuser_mac.mm

#include "focuser.h"
#import <Cocoa/Cocoa.h>

Focuser::Focuser(QWidget *w) {
  this->widget = w;
}

void Focuser::show() {
  this->widget->show();
  this->focus();
}

void Focuser::focus() {
  [NSApp activateIgnoringOtherApps:YES];
  this->widget->activateWindow();
  this->widget->raise();
}

focuser.cpp

#include "focuser.h"

Focuser::Focuser(QWidget *w) {
  this->widget = w;
}

void Focuser::show() {
  this->widget->show();
  this->focus();
}

void Focuser::focus() {
  this->widget->activateWindow();
  this->widget->raise();
}

So we've got one class that takes QWidget in the constructor and has two public methods, one show that shows the widget and focus that focuses the widget. Then we have two definitions of the class, one for Mac OS X in focuser_mac.mm and one in focuser.cpp for any other operating system. The one for the mac additionally calls

[NSApp activateIgnoringOtherApps:YES];

Now, in order for it to compile as it should add this to your .pro file:

HEADERS += focuser.h

mac {
  OBJECTIVE_SOURCES += focuser_mac.mm
}

linux|win32 {
  SOURCES += focuser.cpp
}

When we're done, just add this code where you need your application to be focused:

QWidget *w = new QWidget();
// ...
Focuser f(w);
w.show(); // The widget will now be shown and focused by default.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!