1

X11でQt4.8.3を使用しています。

ユーザーがウィンドウを画面上でドラッグして終了するタイミングを知る必要があります。これは、最終的な位置を読み取り、最終的にアニメーションを開始してウィンドウの位置を「許可された」位置に調整するためです。

QWidget::moveEvent小さな動きごとにが呼び出されることに気づきましたが、ユーザーがマウスボタンを離して動きが完全に終了したときにのみ位置チェックを実行する(そして最終的にはアニメーションを開始する)必要があるため、これは非常に不便です。

これが本当の問題です。タイトルバーはQtではなくOSによって制御されているため、ユーザーがタイトルバーをクリックしたときにマウスリリースイベントを検出する(またはマウスボタンのステータスを取得する)方法がないようです。…でも試してみましたQWidget::x11event(XEvent* e)が、イベントはウィンドウ内でのみ収集され、タイトルバーも収集されません。

誰かがこれを達成する方法を知っていますか?

タイトルバーを自分で再実装する必要があるのではないかと思います…残念です…</p>

4

3 に答える 3

4

私はあなたと同じ問題を抱えています。moveEvent はその移動に沿ったすべてのポイントでトリガーされ、Qt は移動の終わりを把握するための明示的な方法を提供しません。

しかし今、divanov の回答に触発されて、ダイアログを移動した後にマウスを離すと、173 と入力されたイベントが常にトリガーされることがわかりました。それが QEvent::NonClientAreaMouseMove です。

したがって、コードは簡単です。

最初にイベント フィルターをインストールし、メンバー変数をアナウンスします: int nLastEvent;.

bool Win::eventFilter(QObject *obj, QEvent *event)
{
    if (nLastEvent == QEvent::Move && event->type() == 173)
    {
        // do what you wanna do here when the mouse is released,
        // like attaching the dialog to the main window
    }
    nLastEvent = event->type();
    return QWidget::eventFilter(obj, event);
}

シンプルで十分効率的ですよね!

あなたにも役立つことを願っています。:)

于 2012-10-31T03:26:52.747 に答える
1

次のテスト アプリケーションを考えてみましょう: main.cpp

#include <QApplication>

#include "win.h"

int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    Win w;
    w.show();

    return app.exec();
}

win.h:

#include <QWidget>
#include <QEvent>
#include <QMoveEvent>
#include <QDebug>

class Win : public QWidget
{
public:
    Win(QWidget *parent = 0) : QWidget(parent) {
        this->installEventFilter(this);
    }

protected:
    bool eventFilter(QObject *obj, QEvent *event) {
        if (event->type() == QEvent::Move) {
            QMoveEvent *moveEvent = static_cast<QMoveEvent*>(event);
            qDebug() << "Move event:" << moveEvent->pos();
        } else {
            qDebug() << "Event type:" << event->type();
        }
        return QWidget::eventFilter(obj, event);
    }
};

このアプリケーションは、イベント フィルタを自身にインストールし、受信したすべてのイベントを QMoveEvent 用の特別なフォーマットでコンソールに出力し、ログ内でそれを識別します。

典型的なログ:

Event type: 203 
Event type: 75 
Move event: QPoint(0,0) 
Event type: 14 
Event type: 17 
Event type: 26 
Event type: 74 
Event type: 77 
Move event: QPoint(66,52) 
Event type: 12 
Event type: 24 
Event type: 99 
Event type: 77 
Event type: 12 
Event type: 10 
Event type: 11 
Move event: QPoint(308,356) 
Event type: 19 
Event type: 25 
Event type: 99 
Event type: 18 
Event type: 27 
Event type: 77 

ご覧のとおり、アプリケーションが最初に作成されたときの 2 つの移動イベントと、ウィンドウの移動が完了した後の 1 つの移動イベントがあります。私は Qt 4.8.1 と XOrg 7.6 でテストしていました。

生の X イベントを確認するには

  1. テスト アプリケーションを実行します。
  2. テスト アプリケーションのウィンドウ ID を取得します。これを行うには、コマンド ラインxwininfo -name WINDOW_NAMEで実行します。ここWINDOW_NAMEで、 はテスト アプリケーションのウィンドウの名前です。もう 1 つのオプションは、パラメーターなしで xwininfo を使用することです。その場合、マウス ポインターでテスト アプリケーション ウィンドウを選択する必要があります。
  3. X event monitorxev -id 0x2a00002を実行します。ここで0x2a00002、 は前の手順で見つかったウィンドウ ID です。これにより、ウィンドウが X サーバーから受け取る X イベントが出力されます。ConfigureNotifyの X プロトコルに相当するものですQMoveEvent
于 2012-10-18T15:56:13.057 に答える