[QWT] Probleme bei der Dartstellung bei 2 oder mehr QwtPlots

Alles rund um die Programmierung mit Qt
Antworten
TheMetalManiac
Beiträge: 19
Registriert: 21. Juni 2007 15:46

[QWT] Probleme bei der Dartstellung bei 2 oder mehr QwtPlots

Beitrag von TheMetalManiac »

Hallo.
Ich bin auf ein ziemlich komisches Verhalten der QwtPlots gestoßen.
Wenn 2 Instanzen einen QwtPlots erzeugt wurden und einer der beiden läuft, der andere gestoppt ist und man versucht hineinzuzoomen wird die laufende Kurve zum Teil angezeigt...Bilder sagen mehr als Worte(siehe unten die beiden Bilder)

Immer wenn man den zu zoomenden Ausschnitt verändert, wird Counter 2 in der Instanz von Counter 1 aktuallisiert. Es scheint, als ob der Plot der zuletzt ein replot() ausgeführt hat, die canvas beider Plots beschreibt (aber halt nur, wenn man zoomt).

Der Zoomer selbst ist aus den Examples von QWT.

Hier nun mal Code des Zoomers.
Zunächst die Header:

Code: Alles auswählen

class Zoomer: public ScrollZoomer
{
    Q_OBJECT
public:
    Zoomer(QwtPlotCanvas *canvas, QwtPlot *plot);

    virtual void widgetMouseReleaseEvent(QMouseEvent *me)
    {
        if (mouseMatch(MouseSelect2, me))//right mouse-button: zoom out (complete)
        {
            QwtDoubleRect initialRect = zoomBase();
            for (int i = 0; i < MAX_PORT_NUMBER; i++)
            {
                if (pCs[i] != NULL)
                {
                    mDCs[i]->prepareZoomLoDA(initialRect.left(),
                                             initialRect.right());
                }
            }

            zoom(0);
            plot->replot();

        }
        else if (mouseMatch(MouseSelect3, me))//middle mouse-button: zoom out one layer
        {
            int tmpIndex = zoomRectIndex();
            if (tmpIndex >= 1)
                tmpIndex--;
            QwtDoubleRect middleRect = zoomStack()[tmpIndex];

            for (int i = 0; i < MAX_PORT_NUMBER; i++)
            {
                if (pCs[i] != NULL)
                {
                    mDCs[i]->prepareZoomLoDA(middleRect.left(),
                                             middleRect.right());
                }
            }
            zoom(-1);
            plot->replot();
        }

        else
        {

            int tmpIndex = zoomRectIndex();
            QwtDoubleRect lastRect = zoomStack()[tmpIndex];
            for (int i = 0; i < MAX_PORT_NUMBER; i++)
            {
                if (pCs[i] != NULL)
                {
                    //					std::cout << "\nZOOMER: Zoom in Curve: " << i
                    //							<< "   from left: " << lastRect.left()
                    //							<< " to right: " << lastRect.right() << "\n";
                    mDCs[i]->prepareZoomLoDA(lastRect.left(), lastRect.right());
                }
            }

            plot->replot();

        }
        QwtPlotPicker::widgetMouseReleaseEvent(me);
    }

    void Zoomer::autoscaleY(QwtDoubleRect rect)
    {
        //zoomStack()[zoomRectIndex()]=rect;
    }

    virtual void rescale()
    {
        QwtScaleWidget *scaleWidget = plot->axisWidget(yAxis());
        QwtScaleDraw *sd = scaleWidget->scaleDraw();

        int minExtent = 0;
        if (zoomRectIndex() > 0)
        {
            // When scrolling in vertical direction
            // the plot is jumping in horizontal direction
            // because of the different widths of the labels
            // So we better use a fixed extent.

            minExtent = sd->spacing() + sd->majTickLength() + 1;
            minExtent += sd->labelSize(scaleWidget->font(), c_rangeMax).width();
        }

        sd->setMinimumExtent(minExtent);
        ScrollZoomer::rescale();
    }

    void init();
    void setDataContainers(QVector<DataContainer*> dc, int ports);
    void setPlotCurves(QVector<QwtPlotCurve*> pc, int ports);

public slots:

    void updatePlotCanvas(Qt::Orientation, double, double);

private:
    DataContainer * mDCs[MAX_PORT_NUMBER];
    QwtPlotCurve * pCs[MAX_PORT_NUMBER];
    QwtPlotCanvas * canvas;
    QwtPlot * plot;
};
Nun der Konstruktor :

Code: Alles auswählen

Zoomer::Zoomer(QwtPlotCanvas *amy_canvas, QwtPlot *amy_plot) :
        ScrollZoomer(amy_canvas)
{
    plot = amy_plot;
    canvas = amy_canvas;
    std::cout<<"Zoomer: Canvas : "<<&canvas<<"\n";
    ScrollBar * scrollBar = ScrollZoomer::scrollBar(Qt::Horizontal);
    connect(scrollBar, SIGNAL(sliderMoved(Qt::Orientation, double, double)),this, SLOT(updatePlotCanvas(Qt::Orientation, double, double)));
}

Der Zoomer wird in dem von QwtPlot erbenden data_plot initialisiert:

Code: Alles auswählen

//Stops the Plot
void DataPlot::stop()
{
    timer->stop();
    if (plotZoomer == NULL)
    {
        plotZoomer = new Zoomer(canvas(),this);
        std::cout<<"Plot stopped => new Zoomer\n";
        plotZoomer->setRubberBandPen(QPen(Qt::blue, 2, Qt::DotLine));
        plotZoomer->setTrackerPen(QPen(Qt::blue));


        //QVector only to pass the DataContainer
        QVector <DataContainer *>dc;
        QVector <QwtPlotCurve *>pc;
        for (int j = 0; j<ports;j++)
        {
            dc.append(myDataContainers[j]);
            pc.append(plotCurves[j]);
        }
        plotZoomer->setDataContainers(dc,ports);
        plotZoomer->setPlotCurves(pc,ports);
    }
    for (int i = 0; i < ports; i++)
    {
        if (plotCurves[i] !=NULL)
        {
        	//if the raptor is still sampling, the rt data should be stopped
        	myDataContainers[i]->allowSamplingToLoDA(false);
            myDataContainers[i]->prepareStopLoDA();
//            myDataContainers[i]->printLoDA();
            //std::cout<<"S: "<<myDataContainers[i]->getSampleToLoDA()()<<"\n";
            plotCurves[i]->setRawData((xLoDAs[i]),(yLoDAs[i]),myDataContainers[i]->lastLoDAIndex());
        }
    }
    canvas()->setCursor(Qt::CrossCursor);

    running = false;

    setAxisScale(QwtPlot::xBottom,0,lastValue);
    setAxisAutoScale(QwtPlot::yLeft);

    replot();
    plotZoomer->setZoomBase(); //important!Must be set after replot!!!
    PlotLog::info("[Plot " + name + "]: stopped ... now you can zoom.");
}

Hoffentlich sieht einer von euch schnell einen dummen Fehler von mir, das wäre mir am liebsten...sitze schon lange an diesem Fehler.
Die Sourcen von QT und QWT sind aktuell.

Gruß,

TheMetalManiac[/code]
Dateianhänge
Nun wird in Counter 1 reingezoomt:
Nun wird in Counter 1 reingezoomt:
C1gestopptUndZoomaktivertC2läuft.jpg (107.11 KiB) 4757 mal betrachtet
Counter 1 gestoppt, Counter 2 läuft.
Counter 1 gestoppt, Counter 2 läuft.
C1gestopptC2läuft.jpg (107.04 KiB) 4757 mal betrachtet
archer
Beiträge: 306
Registriert: 2. Februar 2006 09:56

Beitrag von archer »

Hat denn jede deine QwtPlot Instanzen seinen eigenen Timer und Zoomer?
TheMetalManiac
Beiträge: 19
Registriert: 21. Juni 2007 15:46

Beitrag von TheMetalManiac »

Ja, jede Instanz erzeugt einen eigenen Zoomer und auch einen eigenen Timer. Übersehe ich dabei was?
archer
Beiträge: 306
Registriert: 2. Februar 2006 09:56

Beitrag von archer »

Kann da in den Code-Framenten leider nichts erkennen.
Habe zwar auch schon bis zu vier QWT Instanzen parallel gehabt, habe aber dort nicht gezoomt. Da hat es keine Probleme gegeben, das der eine in den anderen zeichnet.
erpheus
Beiträge: 46
Registriert: 18. November 2008 11:55
Wohnort: Stuttgart

Beitrag von erpheus »

Hm, bin gerade auch am machen qwt-plots. Was mir auf anhieb einfällt ist, dass Du in der Funktion

Code: Alles auswählen

 void DataPlot::stop()
{
....
replot();
} 
schreibst.

Mach doch daraus mal folgendes:

Code: Alles auswählen

 void DataPlot::stop()
{
....
gezoomterPlot->replot();
} 
Auserdem ist mir aufgefallen das in deinem geposteten Code sehr viele replot() stehen. Schau mal da nach ob die erstens alle nötig sind und jeweils die richtigen plots übergeben werde. Hier solltest du evt. debuggen
TheMetalManiac
Beiträge: 19
Registriert: 21. Juni 2007 15:46

Beitrag von TheMetalManiac »

Danke für eure Antworten,

das replot muss ja auf den QwtPlot selbst und nicht auf dessen Kurven aufgerufen werden. Dem Zoomer übergebe ich das data_plot Objekt (data_plot ist von QwtPlot abgeleitet).
Die replot Aufrufe im Zoomer habe ich komplett aus den IF Zweig gezogen, dass macht wirklich mehr Sinn :).
Uwe
Beiträge: 176
Registriert: 9. Oktober 2005 13:37
Wohnort: München

Beitrag von Uwe »

Die Ursache für solche Fehler kann nur Qt abwärts liegen. Du mußt daher ein lauffähiges Standalone Programm basteln in dem der Fehler auftritt. Da kann ich dann versuchen den Qwt Anteil auszubauen, so daß eine reine Qt Anwendung entsteht, die man an den Trolltech Support schicken kann.

Wenn Du das nicht hinbekommst, mußt Du mit dem Fehler leben oder Dein Programm umgestalten.

Uwe

PS: Hatte ich Dir aber alles schon mal geschrieben.
TheMetalManiac
Beiträge: 19
Registriert: 21. Juni 2007 15:46

Beitrag von TheMetalManiac »

Habe den Fehler gefunden...

Bin gerade nochmal alle Einstellungen des canvas durchgegangen:

es lag an dem QWidget- Attribute setAttribute(Qt::WA_PaintOnScreen) .

Dieses darf nicht eingeschaltet werden, sonst wird der double buffer eingeschaltet.

Gruß,

TheMetalManiac

@Uwe: Ich habe dir 3 Mails geschrieben (seit Oktober 2008) und habe leider keine weitere Antwort erhalten. Die Software ist extrem ineinander verworren und es lässt sich nicht einfach der Plot extrahieren.
Antworten