2016-03-25 11 views
1

ich eine QGridLayout haben, wobei jede Zelle meine benutzerdefinierte Widget QFrameExtended definiert wie folgt enthält:QT5/C++ Release Maus während mouse

In .h:

#ifndef QFRAMEEXTENDED_H 
#define QFRAMEEXTENDED_H 

#include <QObject> 
#include <QFrame> 

class QFrameExtended : public QFrame 
{ 
    Q_OBJECT 

private: 

public: 
    int id; 
    explicit QFrameExtended(QWidget *parent = 0); 

signals: 
    void mousePressEvent(QMouseEvent *); 
    void mouseReleaseEvent(QMouseEvent *); 
    void pressed(QFrameExtended *); 
    void released(QFrameExtended *); 

public slots: 
    void on_mouse_press(); 
    void on_mouse_release(); 
}; 

#endif // QFRAMEEXTENDED_H 

In CPP:

#include "qframe_extended.h" 

QFrameExtended::QFrameExtended(QWidget *parent) : QFrame(parent) 
{ 
    this->id = /* Imagine here there is a function to generate an id */ ; 
    connect(this, SIGNAL(mousePressEvent(QMouseEvent*)), this, SLOT(on_mouse_press())); 
    connect(this, SIGNAL(mouseReleaseEvent(QMouseEvent*)), this, SLOT(on_mouse_release())); 
} 

void QFrameExtended::on_mouse_press() { 
    emit pressed(this); 
} 

void QFrameExtended::on_mouse_release() { 
    emit released(this); 
} 

Mein Formular erstellt die QGridLayout mit den Widgets QFrameExtended und für jede von ihnen definiert einen Event-Handler:

/* ... */ 
/* This snippet of code is inside a loop that is creating frame objects */ 
connect(frame, &QFrameExtended::pressed, this, &MyForm::on_mouse_press); 
connect(frame, &QFrameExtended::released, this, &MyForm::on_mouse_release); 
/* ... */ 

und schließlich das sind die Event-Handler:

void MyForm::on_mouse_press(QFrameExtended *frame) { 
    qDebug() << "Pressed here: " << frame->id << endl; 
} 

void MyForm::on_mouse_release(QFrameExtended *frame) { 
    qDebug() << "Released here: " << frame->id << endl; 
} 

Wenn ich auf eine Zelle klicken (d ein QFrameExtended Widget) ohne die Taste loszulassen, würde ich auf der Konsole die ID der Zelle finden. Nachdem ich die Maus über eine andere Zelle bewegt habe, würde ich, wenn ich den Knopf loslasse, die zweite ID sehen.

Ein Beispiel ist eine Ausgabe wie folgt aus:

hier Gepresste: 1

hier Veröffentlicht: 3

aber die Realität ist, dass, wenn ich drücken Sie die Maustaste über einem QFrameExtended Er fängt an, alle Mausereignisse zu erfassen, bis ich den Knopf loslasse. Dies ist das erwartete Verhalten:

Qt greift automatisch auf die Maus, wenn eine Maustaste in einem Widget gedrückt wird; Das Widget empfängt weiterhin Mausereignisse, bis die letzte Maustaste losgelassen wird.

Von: http://doc.qt.io/qt-4.8/qmouseevent.html

Wie kann ich dieses Verhalten zu ändern? Ich werde wirklich schätzen, wenn Sie mir auch ein Beispiel geben können

+0

invertieren die Logik: nicht akzeptieren, die Maus-Ereignis in den Unter Widgets, lassen Sie es auf den Behälter ausbreiten aus diese Widgets, und darin herausfinden, welches Unter-Widget der Mauszeiger ist ('childAt'). – peppe

Antwort

0

Ok, ich löste die Spitze von peppe. Ich habe versucht, die QGridLayout zu erweitern, aber Layouts unterstützen keine Mausereignisse, da sie nicht von QWidget erben. Also habe ich die QWidget erweitert, die das Layout enthält.

In .h:

#ifndef QWIDGETEXTENDED_H 
#define QWIDGETEXTENDED_H 

#include <QWidget> 
#include <QString> 
#include <QMouseEvent> 
#include "qframe_extended.h" 

class QWidgetExtended : public QWidget 
{ 
    Q_OBJECT 
public: 
    explicit QWidgetExtended(QWidget *parent = 0); 

protected: 
    virtual void mousePressEvent(QMouseEvent *); 
    virtual void mouseReleaseEvent(QMouseEvent *); 

signals: 
    void pressed(QFrameExtended *); 
    void released(QFrameExtended *); 

}; 

#endif 

In CPP:

#include "qwidget_extended.h" 
#include "qframe_extended.h" 

QWidgetExtended::QWidgetExtended(QWidget *parent) : QWidget(parent) 
{ 

} 

void QWidgetExtended::mousePressEvent(QMouseEvent *event) { 
    QFrameExtended frame; 
    QWidget *widget = this->childAt(event->pos()); 
    if (widget != NULL) { 
     QString widgetClassName(widget->metaObject()->className()); 
     //I don't use explicitly the string because if one day someone changes the name of the class, the compiler will output an error 
     QString className(frame.metaObject()->className()); 
     if (widgetClassName == className) { 
      emit pressed(dynamic_cast<QFrameExtended*> (widget)); 
     } 
    } 
} 

void QWidgetExtended::mouseReleaseEvent(QMouseEvent *event) { 
    QFrameExtended frame; 
    QWidget *widget = this->childAt(event->pos()); 
    if (widget != NULL) { 
     QString widgetClassName(widget->metaObject()->className()); 
     //I don't use explicitly the string because if one day someone changes the name of the class, the compiler will output an error 
     QString className(frame.metaObject()->className()); 
     if (widgetClassName == className) { 
      emit released(dynamic_cast<QFrameExtended*> (widget)); 
     } 
    } 
}