QEvent weiterleiten

Alles rund um die Programmierung mit Qt
Antworten
AlGaN
Beiträge: 25
Registriert: 25. März 2006 12:45

QEvent weiterleiten

Beitrag von AlGaN »

Hallo,

ich habe das Problem, dass ich Events, die in einer Klasse auftreten (von QLabel abgeleitet), an eine andere Klasse zur Auswertung weiterleiten muss:

Klasse, die Events fowarden soll (ist in einem DLL-Sub-Projekt)

Code: Alles auswählen

class Map : public QLabel
{
   Q_OBJECT

public:
   Map(QLabel* parent = 0);

[...]

protected:
    virtual void paintEvent(QPaintEvent*);
    virtual void resizeEvent(QResizeEvent*);
    virtual void mousePressEvent(QMouseEvent*);
    virtual void mouseReleaseEvent(QMouseEvent*);
    virtual void mouseMoveEvent(QMouseEvent*);
    virtual void mouseDoubleClickEvent(QMouseEvent*);

[...]
};

Map::Map(QObject* parent)
    : QLabel(parent)
{
    [...]
    setMouseTracking(true);
}
Klasse, die Events verarbeiten soll:

Code: Alles auswählen

class MainWindow : public QMainWindow
{
    Q_OBJECT

    friend class MapEventFilter;

public:
    MainWindow(QObject* parent = 0);

    [...]
    Map* mapWidget() const;

private:
    Map* mMap;

    [...]

    MapEventFilter* mMapFilter;
};

MainWindow::MainWindow
    : QMainWindow(parent)
{
    [...]
    mMapFilter = new MapEventFilter(this);
   
    // create map widget
    mMap = new Map(this);
    // install event filter
    mMap->installEventFilter(mMapFilter);
    [...]
}
und schliesslich die befreundete Filter-Klasse, die die entspr. Events der Map-Klasse abfangen soll:

Code: Alles auswählen

class MapEventFilter : public QObject
{
public:
    MapEventFilter(MainWindow* mw, QObject* parent = 0);

protected:
    bool eventFilter(QObject* dist, QEvent* e);

private:
    MainWindow* mMainWindow;
    Qt::MouseButton mLastButton;
    QPointF mLastMousePos;
    [...]
};
MapEventFilter::MapEventFilter(MainWindow* mw, QObject* parent)
    : mMainWindow(mw), QObject(parent)
{
}

bool MapEventFilter::eventFilter(QObject* dist, QEvent* e)
{
    switch (e->>type())
    {
    case QEvent::MouseButtonPress:
        {
            QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(e);
            
            switch(mMainWindow->mouseMode())
            {
             case MainWindow::MM_Info:
                 // show info of items
                 mMainWindow->showInfo(mouseEvent->pos());
              [...]
          }
          return true;
      case QEvent::MouseButtonRelease:
          [...]
      case QEvent::MouseMove:
           {
                QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(e);
                mMousePos = mouseEvent->pos();
                updateStatusBar(mMousePos);
            }
            return true;
    }
    return QObject::eventFilter(dist, e);
}
Das Problem ist jetzt, dass insbes. bei den MouseMove-Events, in denen u.a. die Anzeige der Koordinaten aktualisiert werden soll in der Statusbar, nicht hinterherkommt, wenn man den Mauszeiger schnell bewegt.

Die Zeile

Code: Alles auswählen

return true
sagt ja laut Doku, dass das entspr. Event damit abgearbeitet ist, d.h. nicht mehr die Event-Methode der ursprünglichen Map-Klasse aufgerufen wird.

Deshalb meine Frage:
- Ist es erlaubt, den Event-Filter in einer Klasse zu definieren, die in einer anderen DLL liegt als die Klasse, deren Events weitergeleitet werden sollen?
- Ist es generell ok, die Events einer Klasse komplett in eine andere Klasse zu forwarden (die Alternative wären Signal-/Slots, die aber noch größere Verzögerung haben).

Danke für alle Hinweise & Tipps

AlGaN[/code]
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Zyklomatische Abhängigkeiten (MapEventFilter kennt MainWindow, MainWindow kennt MapEventFilter) sind schlechtes Design... daher die Frage: warum ist nicht gleich "MainWindow" der Eventfilter?
Ist es erlaubt, den Event-Filter in einer Klasse zu definieren, die in einer anderen DLL liegt als die Klasse, deren Events weitergeleitet werden sollen?
Selbstverständlich... _alle_ Qt-Widgets liegen ja in DLLs, das Beispiel (http://doc.trolltech.com/4.5/qobject.ht ... ventFilter) macht ja genau das...
Ist es generell ok, die Events einer Klasse komplett in eine andere Klasse zu forwarden
Es gibt zwar andere Mittel (z.B. eine abgeleitete Klasse) aber wenn das so gebraucht wird.. warum nicht?
die Alternative wären Signal-/Slots, die aber noch größere Verzögerung haben
Verzögerungen? Wie gemessen?
AlGaN
Beiträge: 25
Registriert: 25. März 2006 12:45

Beitrag von AlGaN »

Hallo solarix,

danke für Deine Antwort. Ok, diese gegenseitige Abhängigkeit ist nicht gut, hatte auch Bauchschmerzen als ich das geschrieben hab, im Prinzip spricht nichts dagegen, den Eventfilter in die MainWindow-Klasse reinzusetzen... hatte nur gedacht, eigentlich gehören die Events ja woanders hin...
Es gibt zwar andere Mittel (z.B. eine abgeleitete Klasse) aber wenn das so gebraucht wird.. warum nicht?
Hier verstehe ich dich nicht genau, was soll eine abgeleitete Klasse bringen, wenn die Events immer noch an der falschen Stelle (in der anderen DLL und nicht im Hauptprogramm) landen?
Verzögerungen? Wie gemessen?
Problem inzwischen gelöst, es lag daran, dass ich bei jedem MouseMove-Event noch ein update() des Widgets gemacht habe, was wohl einen Repaint veranlasst hat (obwohl das ja eigentlich von Qt gemanaged wird (viele aufeinanderfolgende update() => 1 paintEvent())
Antworten