QWidget在Mac OS X不集中在Qt 5.x [英] QWidget on Mac OS X not focusing in Qt 5.x

查看:345
本文介绍了QWidget在Mac OS X不集中在Qt 5.x的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有QSystemTrayIcon与QAction打开类型QWebView的新窗口。当窗口失去焦点,我再次选择QAction,窗口应重新获得焦点。它是在Linux上,但不是在Mac OS X.问题是,当我有另一个窗口打开和活动,让我们说谷歌Chrome浏览器,当我打电话show()我试图打开的窗口,总是在Google Chrome下打开,所以我看不到它。当我打开多个窗口,我的QWebView可能是顺序中的最后一个,当我单击QAction来聚焦窗口,它将始终在谷歌浏览器窗口下,同样的聚焦。我的猜测是,当我点击QAction,这是我的应用程序的过程的一部分,它会尝试打开/聚焦窗口,但在操作中,谷歌Chrome浏览器窗口被安排并获得焦点,因为QSystemTrayIcon不能保持焦点。因此,当窗口被打开/关注时,它不会从谷歌Chrome浏览器中偷取焦点,因为操作系统不允许它,因此它将被放置在当前关注的窗口下。



这里我如何创建/聚焦窗口:

  // ... 
QPointer< QWebView>视图;
// ...

void TrayIcon :: webView(){
if(!this-> view){
this-> view = new QWebView();
this-> view-> load(http://example.com);
this-> view-> show();
} else {
this-> view-> activateWindow();
this-> view-> raise();
}
}

有什么不正确的地方,解决方案

所以我设法解决平台依赖代码的问题。我在.mm文件中创建了带有代码的Focuser类,并且包含了名为Cocoa的Objective-C代码。



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

  #includefocuser.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

  #includefocuser.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();
}

所以我们有一个类在构造函数中使用QWidget,公共方法,显示窗口小部件和焦点的一个显示。然后我们有两个类的定义,一个对于Mac OS X在 focuser_mac.mm 和一个在 focuser.cpp 对于任何其他操作系统。一个为mac另外调用

  [NSApp activateIgnoringOtherApps:YES]; 

现在,为了编译,因为它应该添加到 .pro 文件:

  HEADERS + = focuser.h 

mac {
OBJECTIVE_SOURCES + = focuser_mac.mm
}

linux | win32 {
SOURCES + = focuser.cpp
}

完成后,只需添加此代码,您需要您的应用程序:

  QWidget * w = new QWidget(); 
// ...
Focuser f(w);
w.show(); //该窗口小部件现在将默认显示和聚焦。


I have QSystemTrayIcon with QAction that opens new window of type QWebView. When the window loses focus and I select the QAction again, the window should regain focus. It does on Linux, but doesn't on Mac OS X. The problem is, that when I have another window open and active, let's say Google Chrome, when I call show() on the window I'm trying to open, it always gets opened under the Google Chrome, so I don't see it. The same goes for focusing, when I have multiple windows open, and my QWebView might be the last one in the order, when I click the QAction to focus the window, it will always be under the Google Chrome window. My guess is, that when I click the QAction, which is the part of my application's process, it will try to open/focus the window, but in the middle of the operation, the Google Chrome window gets scheduled and gains focus, since QSystemTrayIcon cannot hold focus. Because of that, when the window gets opened/focused, it will not steal the focus from Google Chrome, because the operating system does not allow it, so it will be placed under currently focused window.

Here how I create/focus the window:

// ...
QPointer<QWebView> view;
// ...

void TrayIcon::webView() {
  if (!this->view) {
    this->view = new QWebView();
    this->view->load("http://example.com");
    this->view->show();
  } else {
    this->view->activateWindow();
    this->view->raise();
  }
}

Is there something I do incorrectly or is there any known workaround?

解决方案

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.

这篇关于QWidget在Mac OS X不集中在Qt 5.x的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆