Qt Live Plot

Alles rund um die Programmierung mit Qt
surfman19
Beiträge: 52
Registriert: 22. August 2008 18:20

Qt Live Plot

Beitrag von surfman19 »

Hallo,

Ich moechte mit Qt daten plotten. Ich empfange jede Sekunde einen neuen Datenpunkt und moechte den dann ins Liniendiagramm hinzufuegen? Bietet Qt was an oder kann ich etwas fertiges verwenden und erweitern?

LG
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Qt Live Plot

Beitrag von Christian81 »

Plotting -> qwt
Oder eben was selbst schreiben - allerdings sollte man da schon etwas auf die Performance schauen.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
surfman19
Beiträge: 52
Registriert: 22. August 2008 18:20

Re: Qt Live Plot

Beitrag von surfman19 »

ok ich versuche es!

kansnt du mir sagen was hier falsch ist?

Code: Alles auswählen

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
	ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

mainwindow.cpp(6): error C2512: 'Ui::MainWindow' : no appropriate default constructor available
bezieht sich auf hier:
ui(new Ui::MainWindow)
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Qt Live Plot

Beitrag von franzf »

Der gepostete Teil ist OK. Hast du evtl selber in ui_mainwindow.h rumeditiert (z.B. Selber nen Konstruktor eingefügt)?
surfman19
Beiträge: 52
Registriert: 22. August 2008 18:20

Re: Qt Live Plot

Beitrag von surfman19 »

die klasse die der moc in der ui_mainwindow.h erzeugt:
class Ui_MainWindowClass

:D
surfman19
Beiträge: 52
Registriert: 22. August 2008 18:20

Re: Qt Live Plot

Beitrag von surfman19 »

Hi,

wie kann ich die groesse des QwtPlot dynamisch skalieren so wie den pushbutton? das QwtPlot hat im moment immer eine fixe groesse ;(
Der Frame welches QwtPlot verwendet ist doch im GridLayout...hm

Code: Alles auswählen

/********************************************************************************
** Form generated from reading UI file 'mainwindow.ui'
**
** Created: Sun 4. Dec 18:19:38 2011
**      by: Qt User Interface Compiler version 4.7.4
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H

#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QFrame>
#include <QtGui/QGridLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QMainWindow>
#include <QtGui/QMenuBar>
#include <QtGui/QPushButton>
#include <QtGui/QStatusBar>
#include <QtGui/QToolBar>
#include <QtGui/QWidget>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>

QT_BEGIN_NAMESPACE

class Ui_MainWindowClass
{
public:
    QWidget *centralWidget;
    QGridLayout *gridLayout;
    QFrame *frame;
    QPushButton *pushButton;
    QMenuBar *menuBar;
    QToolBar *mainToolBar;
    QStatusBar *statusBar;
	QwtPlot *qwtPlot;

    void setupUi(QMainWindow *MainWindowClass)
    {
        if (MainWindowClass->objectName().isEmpty())
            MainWindowClass->setObjectName(QString::fromUtf8("MainWindowClass"));
        MainWindowClass->resize(474, 407);
        centralWidget = new QWidget(MainWindowClass);
        centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
        gridLayout = new QGridLayout(centralWidget);
        gridLayout->setSpacing(6);
        gridLayout->setContentsMargins(11, 11, 11, 11);
        gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
        frame = new QFrame(centralWidget);
        frame->setObjectName(QString::fromUtf8("frame"));
        frame->setFrameShape(QFrame::StyledPanel);
        frame->setFrameShadow(QFrame::Raised);

        gridLayout->addWidget(frame, 0, 0, 1, 1);

		qwtPlot = new QwtPlot(frame);

        pushButton = new QPushButton(centralWidget);
        pushButton->setObjectName(QString::fromUtf8("pushButton"));

        gridLayout->addWidget(pushButton, 1, 0, 1, 1);

        MainWindowClass->setCentralWidget(centralWidget);
        menuBar = new QMenuBar(MainWindowClass);
        menuBar->setObjectName(QString::fromUtf8("menuBar"));
        menuBar->setGeometry(QRect(0, 0, 474, 21));
        MainWindowClass->setMenuBar(menuBar);
        mainToolBar = new QToolBar(MainWindowClass);
        mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
        MainWindowClass->addToolBar(Qt::TopToolBarArea, mainToolBar);
        statusBar = new QStatusBar(MainWindowClass);
        statusBar->setObjectName(QString::fromUtf8("statusBar"));
        MainWindowClass->setStatusBar(statusBar);

        retranslateUi(MainWindowClass);

        QMetaObject::connectSlotsByName(MainWindowClass);
    } // setupUi

    void retranslateUi(QMainWindow *MainWindowClass)
    {
        MainWindowClass->setWindowTitle(QApplication::translate("MainWindowClass", "MainWindow", 0, QApplication::UnicodeUTF8));
        pushButton->setText(QApplication::translate("MainWindowClass", "PushButton", 0, QApplication::UnicodeUTF8));
    } // retranslateUi

};

namespace Ui {
    class MainWindowClass: public Ui_MainWindowClass {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_MAINWINDOW_H
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Qt Live Plot

Beitrag von franzf »

Lies dir bitte mal durch, was in dem ui_mainwindow.h ganz oben steht...
Dass dein label im gridLayout liegt ist ja schön, aber das gridLayout kontrolliert nur die Widgets, die direkt drinnen liegen - children von diesen Widgets fasst es nicht an! (Ist nicht nur bei QGridLayout so, sondern bei jeder Layoutklasse) Du brauchst also ein weiteres Layout im frame, in das du dann dein plot-widget legst.

Zwei Sachen noch:
Du könntest dir viele deiner Fragen sparen, wenn du einfach mal in Ruhe die Doku lesen würdest. Die ist umfangreich und liefert zu so gut wie allem Beispielanwendungen mit.
Desweiteren sollte in jedem Thread nur ein Thema behandelt werden, sonst wirds langsam unübersichtlich. Hier sei dir verziehen, du hast gemeint das Verhalten liegt an QwtPlot. Bitte aber in Zukunft darauf achten, danke :)
surfman19
Beiträge: 52
Registriert: 22. August 2008 18:20

Re: Qt Live Plot

Beitrag von surfman19 »

ok, klappt! thx :)
surfman19
Beiträge: 52
Registriert: 22. August 2008 18:20

Re: Qt Live Plot

Beitrag von surfman19 »

Hallo,

bietet das qwt die moeglichkeit immer nur 25 datenpunkte im plot zu haben? es werden laufend neue hinzugefuegt, dh der älteste datenpunkt muesste dann rausfallen...
ich habe im moment ein array erstellt und verwalte darin nur die 25 aktuellsten daten punkte...
habe in der qwt doku nichts gefunden fuer den spezialfall...

LG
ScyllaIllciz
Beiträge: 200
Registriert: 9. Juli 2010 19:31

Re: Qt Live Plot

Beitrag von ScyllaIllciz »

Die qwt lib kümmert sich nicht um die Daten, sie zeigt nur die Daten an!
Das heißt Du musst Dich selber um Deinen FiFo kümmern!
surfman19
Beiträge: 52
Registriert: 22. August 2008 18:20

Re: Qt Live Plot

Beitrag von surfman19 »

ok, das problem ist wenn ich immer einen datenpunkt loesche und hinzufuege, dann bleibt das diagramm nicht auf den datenbereich zentriert...dh...machmal ist links zwischen ersten datenpunkt und der y achse ein zwischenraum und manchmal auf der rechten seite...
die x achse (zeit) wird laufend erhoeht, und immer nur 20 punkte dargestellt...
verstehst du?

LG
ScyllaIllciz
Beiträge: 200
Registriert: 9. Juli 2010 19:31

Re: Qt Live Plot

Beitrag von ScyllaIllciz »

Du musst schon genau sagen, was Du machen willst. Willst Du einen kontinuierlichen Plot mit immer der selben Anzahl an Punkten oder willst Du einen statischen Plot? Oder zeige ein Bild welchen das Problem darstellt oder ein Bild, wie Du es haben willst oder stell ein Beispiel hier rein, mit dem man das Problem nachvollziehen kann.
surfman19
Beiträge: 52
Registriert: 22. August 2008 18:20

Re: Qt Live Plot

Beitrag von surfman19 »

abstand rechts:
http://img10.imageshack.us/img10/8818/plots.png

abstand links:
http://img710.imageshack.us/img710/9715/plot2n.png

ich will immer die gleiche anzahl an punkten anzeigen....aber mit fortlaufender zeit:

Code: Alles auswählen

curve->setRawSamples(&vec_xval[0], &vec_yval[0], size);
...vec_xval erhoeht laufend
...size bleibt nach 20 werten auf 20
ScyllaIllciz
Beiträge: 200
Registriert: 9. Juli 2010 19:31

Re: Qt Live Plot

Beitrag von ScyllaIllciz »

Also ein kontinuierlicher Plot mit der selben X-Achsen Auflösung, richtig?
So wie ich das sehe benutz Du std::vector. Damit habe ich sowas schon gemacht. Der Trick dabei ist die X-Achsenskalierung um die Aktualisierungsrate zu verschieben. D.h. wenn du z.B. jede Sekunde einen neuen Wert hast, musst Du X-Achsauflösung um 1s verschieben.
In Code:

Code: Alles auswählen

    double dbPlot1_XShiftStart=m_Plot1_samples_x[Plot1_MaxValue-1];
    rotate(m_Plot1_samples_x.begin(), m_Plot1_samples_x.begin()+MaxSpsValues, m_Plot1_samples_x.end());
    rotate(m_Plot1_samples_1.begin(), m_Plot1_samples_1.begin()+MaxSpsValues, m_Plot1_samples_1.end());
    rotate(m_Plot1_samples_2.begin(), m_Plot1_samples_2.begin()+MaxSpsValues, m_Plot1_samples_2.end());

    for (int i=0; i<MaxSpsValues; i++){
            m_Plot1_samples_1[Plot1_MaxValue-MaxSpsValues+i]=m_listBuffer11.at(i).value.toDouble();
            m_Plot1_samples_2[Plot1_MaxValue-MaxSpsValues+i]=m_listBuffer21.at(i).value.toDouble();
            m_Plot1_samples_x[Plot1_MaxValue-MaxSpsValues+i]=dbPlot1_XShiftStart+(i+1)*Plot1_TimeStep;
    }

    m_Plot1_timeOffset+=Plot1_TimeScale;
    ui.qwtPlot->setAxisScale(QwtPlot::xBottom, m_Plot1_timeOffset, m_Plot1_timeOffset+Plot1_TimeBase);

    m_Plot1_curve_1->setRawSamples(&m_Plot1_samples_x[0], &m_Plot1_samples_1[0], Plot1_MaxValue);
    m_Plot1_curve_2->setRawSamples(&m_Plot1_samples_x[0], &m_Plot1_samples_2[0], Plot1_MaxValue);
    ui.qwtPlot->replot();
In Worten. Vector wird um die Zeit x rotiert und der letzte/neue Wert bzw. die letzten/neuen Werte werden mit aktuellen Werten überschrieben. Jetzt noch die X-Achsenskalierung verschieben und fertig.

Ich hoffe Du verstehst was ich meine!
surfman19
Beiträge: 52
Registriert: 22. August 2008 18:20

Re: Qt Live Plot

Beitrag von surfman19 »

ja!
hab das so gemacht...nicht so schoen wie du :)
ist bei dir size immer gleich gross?

Code: Alles auswählen

	int Plot1_TimeScale = 1;
	int Plot1_TimeBase = DATA_POINTS-2;
	static int Plot1_timeOffset = 0;

	if(vec_xval.size() >= DATA_POINTS) 
	{
		vec_xval.erase (vec_xval.begin(), vec_xval.begin()+1);
		vec_yval.erase (vec_yval.begin(), vec_yval.begin()+1);
	}

	vec_xval.push_back(sx);
	vec_yval.push_back(yvalue);

	if(vec_xval.size() == DATA_POINTS)
	{
		Plot1_timeOffset += Plot1_TimeScale;
	}

    ui->qwtPlot->setAxisScale(2, Plot1_timeOffset, Plot1_timeOffset + Plot1_TimeBase);

	if(size < DATA_POINTS)
	{
		size++;
	}
	curve->setRawSamples(&vec_xval[0], &vec_yval[0], size);
	sx++;
	curve->setSymbol(new QwtSymbol(QwtSymbol::Cross, Qt::NoBrush,QPen(Qt::black), QSize(5, 5) ) ); 
	curve->setPen(QColor(Qt::darkGreen));
	curve->setStyle(QwtPlotCurve::Lines);
	curve->attach(ui->qwtPlot);
    ui->qwtPlot->replot();
Antworten