2013-07-01 39 views
10

Tôi có QSystemTrayIcon với QAction mở cửa sổ mới của loại QWebView. Khi cửa sổ mất tiêu điểm và tôi chọn lại QAction, cửa sổ sẽ lấy lại tiêu điểm. Nó có trên Linux, nhưng không có trên Mac OS X. Vấn đề là, khi tôi có một cửa sổ khác mở và hoạt động, giả sử Google Chrome, khi tôi gọi show() trên cửa sổ tôi đang cố gắng mở, nó luôn được mở trong Google Chrome, vì vậy tôi không thấy nó. Cũng giống như khi lấy nét, khi tôi có nhiều cửa sổ đang mở và QWebView của tôi có thể là cửa sổ cuối cùng theo thứ tự, khi tôi nhấp vào QAction để tập trung cửa sổ, nó sẽ luôn nằm trong cửa sổ Google Chrome. Tôi đoán, khi tôi nhấp vào QAction, đó là một phần của quy trình ứng dụng của tôi, nó sẽ cố gắng mở/lấy nét cửa sổ, nhưng ở giữa thao tác, cửa sổ Google Chrome được lên lịch và lấy nét, vì QSystemTrayIcon không thể giữ lấy nét. Do đó, khi cửa sổ được mở/lấy nét, nó sẽ không lấy tiêu điểm từ Google Chrome, bởi vì hệ điều hành không cho phép nó, vì vậy nó sẽ được đặt dưới cửa sổ hiện đang tập trung.QWidget trên Mac OS X không tập trung vào Qt 5.x

đây như thế nào tôi có thể tạo/tập trung các cửa sổ:

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

Có cái gì tôi làm không đúng cách hoặc là có bất kỳ workaround biết?

Trả lời

6

Vì vậy, tôi đã khắc phục sự cố với mã phụ thuộc nền tảng. Tôi đã tạo ra lớp Focuser với mã trong tệp .mm và chứa mã Objective-C được gọi là 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(); 
} 

Vì vậy, chúng tôi đã có một lớp mà có QWidget trong các nhà xây dựng và có hai phương pháp công khai, một chương trình hiển thị tiện ích con và tiêu điểm tập trung vào tiện ích. Sau đó, chúng tôi có hai định nghĩa của lớp học, một cho Mac OS X trong focuser_mac.mm và một trong số focuser.cpp cho bất kỳ hệ điều hành nào khác. Một cho mac gọi thêm

[NSApp activateIgnoringOtherApps:YES]; 

Bây giờ, để biên dịch, hãy thêm số này vào .pro file:

HEADERS += focuser.h 

mac { 
    OBJECTIVE_SOURCES += focuser_mac.mm 
} 

linux|win32 { 
    SOURCES += focuser.cpp 
} 

Khi chúng tôi thực hiện xong, bạn chỉ cần thêm đoạn mã này khi bạn cần ứng dụng của bạn được tập trung:

QWidget *w = new QWidget(); 
// ... 
Focuser f(w); 
w.show(); // The widget will now be shown and focused by default. 
6

Một chút Offtopic, nhưng nó có thể có ích cho một số người dùng:

đề nghị của tôi là để tạo nền tảng mã phụ thuộc để buộc nâng cao của cửa sổ. Có cùng một vấn đề trên nền tảng Windows, vì vậy tôi đang sử dụng xe cho thuê tiếp theo:

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 
    } 

tôi vẫn không cung cấp khả năng tương thích Mac OS trong dự án của tôi, do đó, mã này không có chức năng cho nền tảng không phải giành chiến thắng.

Một ý tưởng khác: bạn nên luôn giữ cửa sổ hiển thị tập trung. Hãy thử làm một với WA_TranslucentBackground | WA_TransparentForMouseEvents thuộc tính + cờ FramelessWindowHint. Vì vậy, ứng dụng của bạn sẽ không bao giờ mất tập trung.

+0

Thật không may, đây không phải tác phẩm trong các cửa sổ 10 –