Pregunta

I tiene un comportamiento extraño en Qt que parece como un defecto. Me gustaría saber si alguien tiene una buena solución.

Tengo un aparato de ventana emergente que contiene muchos botones en ella. El usuario activa la ventana emergente pulsando el botón del ratón. El emergente widget de llama grabMouse cuando se muestra. Se pone todos los eventos de ratón. A medida que rueda sobre un botón que llama setDown(true) en el botón. Ahora, sin embargo, cuando el botón del ratón se suelta el widget de popup no recibe la mouseReleaseEvent, que va al botón.

Es decir, llamando setDown(true) en un botón hace que el botón de robar eventos de ratón, sin pasar por el grabMouse en el aparato de ventana emergente.

He mirado en el código fuente de setDown pero no puedo ver nada allí que lo haría directamente. Asimismo, no cuenta sin embargo que a veces se pone un botón de un evento de vuelo estacionario, a veces. Yo supongo que nunca llegaría a esos eventos cuando se agarró al ratón.

//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;
}
¿Fue útil?

Solución

He entrado en el defecto en el Nokia DB . Estoy dándole una probabilidad del 95% que se cierran como "funciona como está previsto".

Para aquellos de ustedes que necesitan una solución, sin embargo, tendrá que utilizar filtros de eventos y crear su propia atención. Básicamente instalar un filtro de eventos para cada widget hijo y propagar los eventos de ratón para el padre.

Nota en el código anterior que el botón derecho del ratón no funciona incluso si usted no llama setDown.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top