IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qwt Discussion :

QwtPlotZoomer et arrivée continue de données


Sujet :

Qwt

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2009
    Messages : 1 009
    Par défaut QwtPlotZoomer et arrivée continue de données
    Bonjour,

    Je découvre Qwt (version 6.0.1) dans le but d'intégrer un Widget capable d'afficher une courbe en recevant des ordonnées (avancée sur les abscisses pixel par pixel). Je galère énormément.

    Comportement :
    L'axe des ordonnées est laissé libre (pour le moment) donc en autoscaling. L'axe des abscisses, lui, s'initialise de la taille du widget (car 1 pixel = 1 unité). Son pas, pour être lisible, est de disons 10 unités.
    Les premiers points arrivent, on part de zéro. Lorsque la longueur est remplie, on décale d'un pas vers la gauche, et à partir de là ça décale régulièrement. Les valeurs affichées sont stockées dans un QVector, ce qui veut dire que lors du décalage, on efface les "pas" premières valeurs.

    Problème : gestion d'un zoom
    Pour gérer le zoom, j'ai choisi de garder en permanence un QRectF représentant la zoomBase. Ceci afin de ne pas dézoomer ou décaler l'affichage lors d'un décalage des données si l'écran est zoomé. Donc en dézoomant, on ne revient pas forcément à la vue avant le zoom, mais à la vue courante vu qu'entre temps il a pu y avoir des décalages.
    Or, setZoomBase a un comportement inattendu et je n'y arrive tout simplement pas.

    Voici le code : il s'agit de base d'un projet graphique "sample" basé sur un QWidget, et voici les Widget.h et Widget.cpp. L'arrivée de donnée est simulée avec un QTimer et un nombre aléatoire.

    Widget.ui
    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>Widget</class>
     <widget class="QWidget" name="Widget">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>564</width>
        <height>377</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>Widget</string>
      </property>
      <layout class="QHBoxLayout" name="horizontalLayout">
       <item>
        <layout class="QVBoxLayout" name="verticalLayout">
         <property name="spacing">
          <number>0</number>
         </property>
         <item>
          <widget class="QPushButton" name="reset">
           <property name="text">
            <string>Reset</string>
           </property>
          </widget>
         </item>
        </layout>
       </item>
      </layout>
     </widget>
     <layoutdefault spacing="6" margin="11"/>
     <resources/>
     <connections/>
    </ui>

    Widget.h
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    #ifndef WIDGET_H
    #define WIDGET_H
     
    #include <QWidget>
    #include <QTimer>
     
    namespace Ui {
        class Widget;
    }
     
    class QwtPlot;
    class QwtPlotGrid;
    class QwtPlotCurve;
    class QwtPlotZoomer;
     
    class Widget : public QWidget
    {
        Q_OBJECT
     
    public:
        explicit Widget(QWidget *parent = 0);
        ~Widget();
     
    private:
        Ui::Widget *ui;
     
        QVector<QPointF> points;
        qreal curX;
        QTimer timer;
     
        QwtPlot* m_pPlot;
        QwtPlotCurve* m_pCurve;
        QwtPlotGrid* m_pGrid;
        int stepSize;
        QRectF m_BaseRec;
        QwtPlotZoomer* m_pZoomer;
     
    private slots:
        void newValue();
        void resetBottomAxis();
    };
     
    #endif // WIDGET_H

    Widget.cpp
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    #include "Widget.h"
    #include "ui_Widget.h"
     
    #include <QDebug>
    #include <QTime>
     
    #include <qwt_plot.h>
    #include <qwt_plot_grid.h>
    #include <qwt_plot_curve.h>
    #include <qwt_plot_canvas.h>
    #include <qwt_plot_layout.h>
    #include <qwt_plot_zoomer.h>
    #include <qwt_plot_panner.h>
    #include <qwt_plot_magnifier.h>
    #include <qwt_plot_directpainter.h>
     
    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget),
        curX(0),
        stepSize(10),
        m_pPlot( new QwtPlot(this) ),
        m_pCurve(new QwtPlotCurve),
        m_pGrid(new QwtPlotGrid)
    {
        ui->setupUi(this);
     
        m_pPlot->canvas()->setPaintAttribute(QwtPlotCanvas::BackingStore, false);
        m_pPlot->setCanvasBackground(Qt::black);
        m_pCurve->setPen(QColor(Qt::green));
     
        m_pCurve->setRenderHint(QwtPlotItem::RenderAntialiased);
        m_pGrid->setPen(QColor(Qt::white));
        m_pPlot->plotLayout()->setAlignCanvasToScales(true);
        m_pCurve->attach(m_pPlot);
        m_pGrid->attach(m_pPlot);
     
        m_pZoomer = new QwtPlotZoomer( m_pPlot->canvas() );
        m_pZoomer->setRubberBandPen(QColor(Qt::red));
        m_pZoomer->setTrackerPen(QColor(Qt::red));
        m_pZoomer->setTrackerMode(QwtPlotZoomer::AlwaysOn);
        m_pZoomer->setMousePattern( QwtEventPattern::MouseSelect2,
            Qt::RightButton, Qt::ControlModifier );
        m_pZoomer->setMousePattern( QwtEventPattern::MouseSelect3,
            Qt::RightButton );
     
        (void) new QwtPlotMagnifier( m_pPlot->canvas() );
     
        connect(&timer, SIGNAL(timeout()), SLOT(newValue()));
        connect(ui->reset, SIGNAL(clicked()), SLOT(resetBottomAxis()));
     
        qsrand(QTime::currentTime().msec());
        timer.start(200);
        ui->verticalLayout->addWidget(m_pPlot);
        m_BaseRec.setWidth(m_pPlot->canvas()->width());
        m_BaseRec.setHeight(m_pPlot->canvas()->height());
        resetBottomAxis();
    }
     
    Widget::~Widget()
    {
        delete m_pPlot;
        delete ui;
    }
     
    void Widget::newValue()
    {
        qDebug() << m_BaseRec.top() << m_BaseRec.bottom();
        points << QPointF(curX++, qrand()%201 - 100);
     
        if (points.size() > m_BaseRec.width()) {
            points.remove(0, stepSize);
            m_pCurve->setSamples(points);
     
            m_BaseRec.moveRight(m_BaseRec.right()+stepSize);
            qDebug() << "**** APRES moveRight ****" << m_BaseRec;
            qDebug() << "**** AVANT setZoomBase ****" << m_pZoomer->zoomBase();
            m_pZoomer->setZoomBase(m_BaseRec);
            qDebug() << "**** APRES setZoomBase ****" << m_pZoomer->zoomBase();
            //if (m_pZoomer->zoomRectIndex() >= 1) {
                resetBottomAxis();
                m_pPlot->replot();
            //}
        } else {
            m_pCurve->setSamples(points);
            QwtPlotDirectPainter directPainter;
            const double& d = m_pPlot->axisScaleDiv(QwtPlot::xBottom)->lowerBound();
            directPainter.drawSeries(m_pCurve, curX-2-d, curX-1-d);
        }
     
        if (points.last().y() > m_BaseRec.bottom()) {
            m_BaseRec.setBottom(points.last().y());
            m_pZoomer->setZoomBase(m_BaseRec);
            //if (m_pZoomer->zoomRectIndex() >= 1) {
                m_pPlot->replot();
            //}
        } else if (points.last().y() < m_BaseRec.top()) {
            m_BaseRec.setTop(points.last().y());
            m_pZoomer->setZoomBase(m_BaseRec);
            //if (m_pZoomer->zoomRectIndex() >= 1) {
                m_pPlot->replot();
            //}
        }
        qDebug() << m_pZoomer->zoomRectIndex() << " : " << m_pZoomer->zoomBase();
    }
     
    void Widget::resetBottomAxis() {
        m_pPlot->setAxisScale(QwtPlot::xBottom, m_BaseRec.left(), m_BaseRec.right(), stepSize);
    }

    Déjà je ne comprends pas pourquoi le m_pZoomer->zoomRectIndex() donne 1 tout le temps au lieu de 0 (clic droit pour dézoomer et on a 0 jusqu'au prochain changement de canvas où ça repasse à 1). Ensuite le setZoomBase force le zoomRectIndex à 1, alors que l'idée est juste de modifier la base (le 0 de la pile normalement) pendant qu'on est zoomé.
    En espérant votre aide

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 23
    Par défaut
    Franchement si l'anglais ne te rebute pas vas poster ta question ici : http://www.qtcentre.org/forums/23-Qwt
    L'auteur de Qwt (Uwe) répondra.

Discussions similaires

  1. Réponses: 6
    Dernier message: 11/06/2015, 16h52
  2. Réponses: 8
    Dernier message: 24/11/2011, 14h09
  3. Réponses: 2
    Dernier message: 05/12/2006, 22h10
  4. Réponses: 13
    Dernier message: 24/05/2006, 10h27
  5. [C#] Je n'arrive pas à remonter les données
    Par Le Basque dans le forum Windows Forms
    Réponses: 14
    Dernier message: 17/01/2005, 19h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo