Seite 1 von 1

[gelöst] 'qwt zoomer' inkl. 'AxisAutoScale' möglich?

Verfasst: 26. Februar 2010 16:50
von topo
Hallo Qt und Qwt Interessierte,

ich habe aktuell ein Problem mit meinem QwtPlot Widget. Ich habe QwtPlotCurves, die ich variabel hinzufügen und entfernen kann. Zur besseren Darstellung habe ich die Autoskalierung eingeschaltet und dies funktioniert auch sehr gut.

Leider habe ich nach hinzufügen des Qwt Zoomers diese super Funktion leider verloren, denn wenn ich hineinzoome wird natürlich eine andere Skalierung genommen, aber auch beim hinauszoomen wird nicht mehr in die ursprüngliche Auflösung gewechselt, sondern eine von der Zoomer Klasse festgelegt. Zudem funktioniert danach der ganze Autoscale nicht mehr :( .

:?: Nun meine Frage: Gibt es eine Möglichkeit beides zu Verbinden? Ich möchte die Autoskalierung nutzen, in eine Kurve hineinzoomen können und wenn ich wieder hinauszoome oder eine neue Kurve hinzufüge wieder in die Autoskalierung wechseln. Geht das? Wenn ja, wie?

Anbei mein aktueller Code aus der Initialisierung, der replot findet an anderer Stelle bei der Selektion einer anzuzeigenden Kurve als slot des signals currentIndexChanged der QComboBox statt:

Code: Alles auswählen


    m_pPlotWidget = new QwtPlot(m_pFrameBackground);
    m_pPlotWidget->setCanvasBackground( QColor(0,0,0) );

    QwtPlotGrid *grid = new QwtPlotGrid();
    grid->setPen( QPen(Qt::gray, 0.0, Qt::DotLine) );
    grid->enableX(true);
    grid->enableXMin(false);
    grid->enableY(true);
    grid->enableYMin(false);
    grid->attach(m_pPlotWidget);

    QFont axisFont("Arial", 10);
    m_pPlotWidget->setAxisFont(QwtPlot::yLeft, axisFont);
    m_pPlotWidget->setAxisFont(QwtPlot::xBottom, axisFont);

    // Enable axis auto scale
    m_pPlotWidget->setAxisAutoScale(QwtPlot::xBottom);
    m_pPlotWidget->setAxisAutoScale(QwtPlot::yLeft);

    m_pPlotWidget->plotLayout()->setAlignCanvasToScales(true);

    QwtPlotZoomer* zoomer = new CGuiPlotWidgetZoomer( m_pPlotWidget->canvas() );
#if QT_VERSION < 0x040000
    zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
        Qt::RightButton, Qt::ControlButton);
#else
    zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
        Qt::RightButton, Qt::ControlModifier);
#endif
    zoomer->setMousePattern(QwtEventPattern::MouseSelect3,
        Qt::RightButton);

    QwtPlotPanner *panner = new QwtPlotPanner( m_pPlotWidget->canvas() );
    panner->setAxisEnabled(QwtPlot::yRight, false);
    panner->setMouseButton(Qt::MidButton);

    const QColor c(Qt::darkBlue);
    zoomer->setRubberBandPen(c);
    zoomer->setTrackerPen(c);

Vielen Dank schon im Voraus für Eure Hilfe :D .

Viele Grüße,
topo

Verfasst: 26. Februar 2010 18:19
von MiKla
Schau mal in den Examples nach. Da gibt es im Bode Example einen Toolbutton, mit dem das zoomen aktivieren kann. Dazu gibt es eine scrollzoomer Klasse (scrollzoomer.h, scrollzoomer, scrollbar.h, scrollbar.h). Diese habe ich direkt in mein Projekt übernommen.

Code: Alles auswählen

...
#include "scrollzoomer.h"
...
Zoomer *zoomer;
...

    zoomer = new Zoomer(qwtPlot->canvas());
    zoomer->setSelectionFlags(QwtPicker::DragSelection | QwtPicker::CornerToCorner);
    zoomer->setRubberBandPen(QPen(Qt::red, 2, Qt::DotLine));
    zoomer->setTrackerPen(QPen(Qt::red));
    zoomer->setTrackerMode(QwtPicker::AlwaysOn);
	zoomer->setHScrollBarPosition(ScrollZoomer::AttachedToScale);
    zoomer->setEnabled(false);
    zoomer->zoom(0);
...
    qwtPlot->replot();
    zoomer->setZoomBase();
...
void QScope::enableZoomMode(bool on)
{
//    panner->setEnabled(on);
    zoomer->setEnabled(on);
    zoomer->zoom(0);
    picker->setEnabled(!on);
    showInfo();
}
Vielleicht hilft Dir das weiter!!!

Michael

Re: 'qwt zoomer' inkl. 'AxisAutoScale' möglich?

Verfasst: 27. Februar 2010 15:03
von Uwe
Leider habe ich nach hinzufügen des Qwt Zoomers diese super Funktion leider verloren, denn wenn ich hineinzoome wird natürlich eine andere Skalierung genommen, aber auch beim hinauszoomen wird nicht mehr in die ursprüngliche Auflösung gewechselt, sondern eine von der Zoomer Klasse festgelegt.
Der Zommer legt keine Auflösung fest, sondern wird mit der aktuellen Auflösung Deines Plots initialisiert. Wenn Du Autoskaling verwendest, mußt Du diese Initialisierung jeweils aktualisieren.
Zudem funktioniert danach der ganze Autoscale nicht mehr :( .
Sobald Du Skalierungen explizit zuweist ( hier durch zoomen ) wird Autoscaling abgeschaltet. D.h. Du musst es wieder anschalten, wenn Du herausgezoomt hast.

Ich würde Dir vorschlagen replot folgendermaßen zu überladen:

Code: Alles auswählen

void YourPlot::replot()
{
    QwtPlot::replot();

    if ( m_zoomer->zoomRectIndex() == 0 ) // not zoomed
    {
        for ( int axis = 0; axis < axisCnt; axis++ )
            setAxisAutoScale(axis, true);

        m_zoomer->setZoomBase(false); // reinitialize zoomer
    }
}
Habe es nicht selber ausprobiert - eventuell gibt es Reihenfolgeprobleme bei replots die vom Zoomer kommen. Aber so oder so ähnlich sollte es gehen.

Uwe

Verfasst: 1. März 2010 18:09
von topo
Danke für Eure guten Hinweise und Tipps. Das hilft mir beides auf alle Fälle weiter! Ich werde sie morgen ausprobieren und mich nochmal melden :D !

Viele Grüße,
Thomas

Verfasst: 2. März 2010 16:21
von topo
Hier das Fazit meiner heutigen Tests :wink: .

@Michael: Die "scrollzoomer.h" ist gut um sich einige Tipps zu holen, für das was ich machen will möchte ich aber nicht die ganze Klasse bei mir includieren, da ich nicht alles davon brauche. Trotzdem danke für den Hinweis :D .

@Uwe: Der Tipp war auch gut, aber im replot kann ich den Index nicht abfragen, da der Konstruktor des Zoomers wiederrum ein Replot auslöst und dadurch in der Replotfunktion auf einen uninitialisierten Pointer zugegriffen wird. Aber anhand des Beispiels habe ich eine Lösung gefunden:

Code: Alles auswählen

        // enable axis auto scale
        m_pPlotWidget->setAxisAutoScale(QwtPlot::xBottom);
        m_pPlotWidget->setAxisAutoScale(QwtPlot::yLeft);

        // replot
        m_pPlotWidget->replot();

        // get axis min and max values to calculate a rectangle for initialize the zoomer
        double xLowerBound = m_pPlotWidget->axisScaleDiv(QwtPlot::xBottom)->lowerBound();
        double xUpperBound = m_pPlotWidget->axisScaleDiv(QwtPlot::xBottom)->upperBound();
        double yLowerBound = m_pPlotWidget->axisScaleDiv(QwtPlot::yLeft)->lowerBound();
        double yUpperBound = m_pPlotWidget->axisScaleDiv(QwtPlot::yLeft)->upperBound();

        // initialize the zoomer with auto scale values
        m_pZoomer->setZoomBase( QwtDoubleRect(xLowerBound, yUpperBound, yUpperBound-yLowerBound, xUpperBound-xLowerBound) );
        // reset zoom level to 0
        m_pZoomer->setZoomBase(false);