2011-01-17 3 views
1

Qtに不具合があるような気がします。誰かが適切な回避策を持っているかどうかを知りたい。Qt QAbstractButton setDownがgrabMouseと干渉します

私は、多くのボタンを含むポップアップウィジェットを持っています。ユーザーは、マウスボタンを押してポップアップをアクティブにします。表示されている場合、ポップアップウィジェットはgrabMouseを呼び出します。すべてのマウスイベントを取得します。ボタンの上を転がると、ボタンの上にsetDown(true)が呼び出されます。ただし、マウスボタンが放されると、ポップアップウィジェットはmouseReleaseEventを取得せず、ボタンに移動します。

つまり、ボタン上でsetDown(true)を呼び出すと、ポップアップウィジェットのgrabMouseをバイパスして、ボタンがマウスイベントを盗み出します。

私はsetDownのソースコードを見てきましたが、それを直接行うことはできません。しかし、ボタンがホバーイベントを取得することもあります。私は、マウスをつかんだときにそれらの出来事を得ることは決してないと思います。

//g++ -o grab_lost grab_lost.cpp -lQtCore -lQtGui -I /usr/include/qt4/ -I /usr/include/qt4/QtCore -I /usr/include/qt4/QtGui 
/** 
    Demonstrates the defect of losing the mouse. Run the program and: 

    1. Press mouse anywhere 
    2. release in purple block (not on X) 
    3. Release message written (GrabLost receives the mouseReleaseEvent) 

    For defect: 

    1. Pree mouse anywhere 
    2. Release inside the X button 
    3. button is clicked, no release message (GrabLost does not get the mouseReleaseEvent) 
*/ 
#include <QWidget> 
#include <QPushButton> 
#include <QApplication> 
#include <QMouseEvent> 
#include <QPainter> 

class GrabLost : public QWidget 
{ 
    QPushButton * btn; 
public: 
    GrabLost(QWidget * parent = 0) 
     : QWidget(parent, Qt::Popup) 
    { 
     btn = new QPushButton("X", this); 
     setMouseTracking(true); 
    } 

protected: 
    void showEvent(QShowEvent * ev) 
    { 
     QWidget::showEvent(ev); 
     grabMouse(); 
    } 
    void closeEvent(QCloseEvent * ev) 
    { 
     releaseMouse(); 
     QWidget::closeEvent(ev); 
    } 
    void hideEvent(QHideEvent * ev) 
    { 
     releaseMouse(); 
     QWidget::hideEvent(ev); 
    } 

    void mouseReleaseEvent(QMouseEvent * ev) 
    { 
     qDebug("mouseRelease"); 
     close(); 
    } 

    void mouseMoveEvent(QMouseEvent * ev) 
    { 
     QWidget * w = childAt(ev->pos()); 
     bool ours = dynamic_cast<QPushButton*>(w) == btn; 
     btn->setDown(ours); 
    } 

    void paintEvent(QPaintEvent * ev) 
    { 
     //just to show where the widget is 
     QPainter pt(this); 
     pt.setPen(QColor(0,0,0)); 
     pt.setBrush(QColor(128,0,128)); 
     pt.drawRect(0, 0, size().width(), size().height()); 
    } 
}; 

class GrabMe : public QWidget 
{ 
protected: 
    void mousePressEvent(QMouseEvent * ev) 
    { 
     GrabLost * gl = new GrabLost(); 
     gl->resize(100, 100); 
     QPoint at(mapToGlobal(ev->pos())); 
     gl->move(at.x() - 50, at.y() - 50); 
     gl->show(); 
    } 
}; 

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

    GrabMe * gm = new GrabMe(); 
    gm->move(100, 100); 
    gm->resize(300, 300); 
    gm->show(); 

    app.exec(); 
    return 0; 
} 

答えて

0

私はNokia DBに欠陥を入力しました。私は約95%の確率で「意図したとおりに働く」ことを約束しています。

解決策が必要な方には、イベントフィルタを使用して独自のグラブを作成する必要があります。基本的にすべての子ウィジェットのイベントフィルターをインストールし、親にマウスイベントを伝播します。

setDownを呼び出さなくても、マウスの右ボタンが機能しないことに注意してください。

関連する問題