ste*_*nak 10 c++ macos qt qwidget qt5
我有QSystemTrayIcon和QAction打开QWebView类型的新窗口.当窗口失去焦点并再次选择QAction时,窗口应重新获得焦点.它在Linux上运行,但在Mac OS X上没有.问题是,当我有另一个窗口打开并处于活动状态时,让我们说Google Chrome,当我在我试图打开的窗口上调用show()时,它总是在谷歌浏览器下打开,所以我没有看到它.聚焦时也是如此,当我打开多个窗口时,我的QWebView可能是订单中的最后一个,当我点击QAction聚焦窗口时,它将始终位于谷歌浏览器窗口下.我的猜测是,当我单击QAction时,它是我的应用程序进程的一部分,它将尝试打开/聚焦窗口,但在操作过程中,由于QSystemTrayIcon无法保持焦点,因此Google Chrome窗口会被安排并获得焦点.因此,当窗口被打开/聚焦时,它不会从谷歌Chrome中窃取焦点,因为操作系统不允许它,因此它将被置于当前聚焦的窗口下.
在这里我如何创建/聚焦窗口:
// ...
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();
}
}
Run Code Online (Sandbox Code Playgroud)
有什么我做错了或有任何已知的解决方法?
有点offtopic,但它可能对某些用户有用:
我的建议是创建平台依赖的代码来强制提升窗口.在Windows平台上存在同样的问题,所以我正在使用下一个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
}
Run Code Online (Sandbox Code Playgroud)
我仍然没有在我的项目中提供Mac OS兼容性,因此此代码对非赢平台没有任何功能.
另一个想法:你应该始终保持专注的可见窗口.尝试用WA_TranslucentBackground |做一个 WA_TransparentForMouseEvents属性+ FramelessWindowHint标志.所以你的应用程序永远不会失去焦点
所以我设法用平台依赖代码解决了这个问题.我使用.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
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
所以我们有一个类在构造函数中使用QWidget并且有两个公共方法,一个显示窗口小部件和聚焦小部件的焦点.然后我们有两个类的定义,一个用于Focusser_mac.mm中的 Mac OS X ,另一个用于任何其他操作系统的focuser.cpp.另外一个用于mac的电话
[NSApp activateIgnoringOtherApps:YES];
Run Code Online (Sandbox Code Playgroud)
现在,为了编译它,它应该将它添加到.pro文件中:
HEADERS += focuser.h
mac {
OBJECTIVE_SOURCES += focuser_mac.mm
}
linux|win32 {
SOURCES += focuser.cpp
}
Run Code Online (Sandbox Code Playgroud)
完成后,只需将此代码添加到您需要关注应用程序的位置:
QWidget *w = new QWidget();
// ...
Focuser f(w);
w.show(); // The widget will now be shown and focused by default.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2245 次 |
| 最近记录: |