Frage

ich einige seltsame Verhalten in Qt haben, der wie ein Defekt scheint. Ich würde gerne wissen, ob jemand eine gute Abhilfe hat.

ich ein Pop-up-Widget haben, dass viele Tasten in es enthält. Der Benutzer aktiviert das Popup, indem Sie die Maustaste nach unten drücken. Das Popup-Widget grabMouse aufruft, wenn gezeigt. Es wird alle Mausereignisse. Da es über einen Knopf rollt nennt es setDown(true) auf die Schaltfläche. Nun aber, wenn die Maustaste wird das Popup-Freigabe-Widget nicht die mouseReleaseEvent erhält, die auf die Taste geht.

Das heißt, ruft setDown(true) auf eine Schaltfläche bewirkt, dass die Taste Mausereignisse stehlen, die grabMouse im Popup-Widget umgangen wird.

Ich habe für setDown auf den Quellcode sehe, aber ich kann nichts sehen dort, dass es direkt tun würde. Ich merke aber auch, dass manchmal eine Taste, um ein Hover-Ereignis wird, manchmal nicht. Ich würde davon ausgehen, es würde nie diese Ereignisse erhalten, wenn die Maus ergriffen wird.

//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;
}
War es hilfreich?

Lösung

Ich habe den Fehler bei der Nokia DB . Ich bin es sich um eine 95% Chance, dass sie es so nah „Arbeiten wie vorgesehen.“

Für diejenigen von Ihnen, die eine Lösung benötigen, dennoch werden Sie Ereignisfilter verwenden und deine eigenen Grabbing erstellen. Grundsätzlich installieren Sie ein Ereignisfilter für jedes Kind-Widget und propagieren die Mausereignisse an die Eltern.

Beachten Sie im obigen Code, dass die rechte Maustaste auch dann nicht funktionieren, wenn Sie setDown nicht nennen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top