2017-06-07 7 views
-3

QtクリエイターでC++でコーディングしています。画面上にすべてのウィンドウを表示できますが、動きを直接検出したいと思います。ウィンドウから放射される信号によって動きを検出する方法はありますか?ウィンドウ位置を直接検出する方法は?

+0

* "画面上のすべてのウィンドウ" * - でも意味することになっていることは何ですか? – IInspectable

+0

ナビゲータのようなすべてのウィンドウ、開かれたアプリケーション、.... – andresouris

+0

[OK]を、その場合、私はあなたに挑戦します* "画面上のすべてのウィンドウを取得する" *。 UIPIは信頼性の低いプロセスが高い完全性を持つリソースにアクセスできるようにするために、納得するほどの痛みを感じています。しかし、とにかく、あなたはあなたのターゲットプラットフォームについて完全に間違った理解を持っています。 Qtは、Qtを知らないウィンドウのためのどんな種類のシグナルも放出しません。 – IInspectable

答えて

-1

ターゲットウィンドウからQWindowを作成し、それをQWidget :: createWindowContainer()を使用してQWidgetにラップすることができます。

あなたはこのQTBUGのスレッドを見て持つことができます。https://bugreports.qt.io/browse/QTBUG-40320

それが適切に動作させるためにいくつかの努力を必要とします。キャプチャされたウィンドウは初期のディメンションを保持せず、ウィンドウを解放すると変な動作をします。最後のQTBUGのコメントを読んで改善を見いだす。

このコードにイベントフィルタを追加して、リアルタイムでウィンドウの位置を取得しました。しかしそれは満足できないかもしれません。

class EventFilter : public QObject 
{ 
    Q_OBJECT 

public: 
    EventFilter(){} 
    virtual ~EventFilter(){} 

protected: 
    bool eventFilter(QObject *obj, QEvent *event); 
} ; 


bool EventFilter::eventFilter(QObject *obj, QEvent *event) 
{ 
    qDebug() << event->type() ; 

    if (event->type() == QEvent::Move) { 
     QMoveEvent *moveEvent = static_cast<QMoveEvent *>(event); 
     qDebug() << "position" << moveEvent->pos() ; 
     return true; 
    } else { 
     // standard event processing 
     return QObject::eventFilter(obj, event); 
    } 
} 

QTBUGスニペットからパート3を削除し、内部ウィジェットにイベントハンドラをインストールしました。タイマーを削除することもできます。

// From https://bugreports.qt.io/browse/QTBUG-40320 
int main(int argc, char *argv[]) 
{  
    // Windows: Find HWND by window title 
    WId id = (WId)FindWindow(NULL, L"Calculator"); 
    if (!id) 
     return -1; 

    QApplication a(argc, argv); 
    // Optional 
    QTimer t; 
    t.start(2500); 

    // Part 1 
    QWindow* window = QWindow::fromWinId(id); 
    window->show(); 
    window->requestActivate(); 

    // Optional 
    QObject::connect(&t, &QTimer::timeout, [=] 
    { 
     qDebug() << "=== Inner QWindow ==="; 
     qDebug() << "Geometry:" << window->geometry(); 
     qDebug() << "Active?:" << window->isActive(); 
     qDebug() << "Flags:" << window->flags(); 
    }); 

    // Part 2 
    QWidget* widget = QWidget::createWindowContainer(window); 
    widget->show(); 

    // Optional 
    QObject::connect(&t, &QTimer::timeout, [=] 
    { 
     qDebug() << "=== Outer QWidget ==="; 
     qDebug() << "Geometry:" << widget->geometry(); 
     qDebug() << "Active?" << widget->isActiveWindow(); 
     qDebug() << "Flags:" << widget->windowFlags(); 
    }); 

    // Realtime position 
    EventFilter filter ; 
    widget->installEventFilter(&filter) ; 


    return a.exec(); 
} 

出力:

=== Inner QWindow === 
Geometry: QRect(0,0 640x480) 
Active?: true 
Flags: QFlags<Qt::WindowType>(ForeignWindow) 
=== Outer QWidget === 
Geometry: QRect(2489,29 640x480) 
Active? true 
Flags: QFlags<Qt::WindowType>(Window|WindowTitleHint|WindowSystemMenuHint|WindowMinMaxButtonsHint|WindowCloseButtonHint) 

QEvent::Type(Move) 
position QPoint(2484,29) 
QEvent::Type(Move) 
position QPoint(2481,30) 
QEvent::Type(Move) 
position QPoint(2478,31) 
QEvent::Type(Move) 
position QPoint(2474,31) 

も参照してくださいhttp://blog.qt.io/blog/2013/02/19/introducing-qwidgetcreatewindowcontainer/

+0

UIPIの境界を越えて作業できません。そして、別のスレッドが所有するウィンドウに手を差し伸べるには、あなたがやっていること**を正確に知っていて、適切な共用のために両方のスレッドのコードを制御する必要があります。いずれのスレッドでもコードを制御することはできません。この**は壊れます**。 – IInspectable

+0

P.S .: [WinEvents](https://msdn.microsoft.com/en-us/library/windows/desktop/dd373868.aspx)を使用する堅牢なソリューションです。 – IInspectable

関連する問題