簡體   English   中英

Qt QAbstractButton setDown干擾了grabMouse

[英]Qt QAbstractButton setDown interferes with grabMouse

我在Qt中有一些奇怪的行為,似乎是一個缺陷。 我想知道是否有人有很好的解決方法。

我有一個彈出窗口小部件,其中包含許多按鈕。 用戶通過按下鼠標按鈕來激活彈出窗口。 顯示時,彈出窗口小部件將調用grabMouse 它獲取所有鼠標事件。 setDown(true)懸停在按鈕上時,它將在按鈕上調用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;
}

我已經在諾基亞數據庫中輸入了缺陷。 我給了他們95%的機會,讓他們按照“預期的工作方式”將其關閉。

對於那些需要解決方案的人,您將不得不使用事件過濾器並創建自己的抓取工具。 基本上為每個子窗口小部件安裝一個事件過濾器,並將鼠標事件傳播到父窗口。

請注意,在上面的代碼中,即使不調用setDown鼠標右鍵也setDown

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM