Results 1 to 4 of 4

Thread: Problem using QwtPlotCanvas::paintCache();

  1. #1
    Join Date
    Aug 2009
    Location
    San José, Costa Rica
    Posts
    4
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Problem using QwtPlotCanvas::paintCache();

    I wrote a very simple aplication: reads a data from a text file and plots it out. Works fine. Now I want to be able to stream the plot so that the following command runs:
    my_simple_application | other_application
    Tried the following after the plot is displayed:

    application reads data .
    plot is created.
    .
    .
    grafScree->show(); // No problem up to here

    QwtPlotCanvas grafCanvas(grafScree );
    if ( grafCanvas.testPaintAttribute( QwtPlotCanvas::PaintCached ) ) cout << "PaintCached activated" << endl; else cout << "PaintCached not activated" << endl;

    QPixmap *pmGraf = grafCanvas.paintCache();
    if ( pmGraf->isNull() ) cout << "Pixmap not created."<<endl;
    if (pmGraf->isQBitmap() ) cout << "It is a bitmap."<<endl;
    cout << pmGraf;

    Observations:
    a) "PaintCached activated" is reported
    b) "Pixmap not created." is reported
    c) Allthough the pixmap is not created, something gets streamed out ( ¿garbage?)
    The command

    ./prupixmap | display

    where display refers to ImageMagick´s program produces the following error

    display: no decode delegate for this image format `/tmp/magick-XXj30Mz2'

    ///////////////////////////
    Using:
    Qwt 5.2.0
    Qt 4.5.2
    Suse Linux 10.1
    Dell Optiplex 360
    ///////////////// Full program

    #include <iostream>
    using std::cerr;
    using std::endl;
    using std::cout;
    using std::cin;

    #include <QApplication>
    #include <QString>
    #include <QStringList>
    #include <QFile>
    #include <QTextStream>
    #include <QVector>
    #include <QDateTime>
    #include <QPixmap>
    #include <QImage>

    // Añadidos para incluir Qwt

    #include <qwt_plot.h>
    #include <qwt_plot_curve.h>
    #include <qwt_symbol.h>
    #include <qwt_data.h>
    //#include <qwt_painter.h>
    #include <qcolor.h>
    #include <qwt_plot_canvas.h>


    // QT_BEGIN_NAMESPACE
    // class QRubberBand;
    // QT_END_NAMESPACE


    int leeVarMet(QString *nArch, QVector<QDateTime> *vDT, QVector<double> *vV );

    int leeVarMet(QString &nArch, QVector<QDateTime> *vDT, QVector<double> *vV )
    {
    QFile aEnt(nArch);

    if (!aEnt.open(QIODevice::ReadOnly | QIODevice::Text)){
    std::cerr << "No se pudo abrir el archivo de entrada" << endl;
    return -1;
    }
    QTextStream entra(&aEnt);

    QString linea = entra.readLine(81);
    int c =0;

    while (!linea.isNull()) {
    // cout << qPrintable(linea) << endl;
    QStringList lista = linea.split("\t");
    bool ok = false;
    if (lista.size() == 2) {
    QDateTime dtObj = QDateTime::fromString(lista[0], "yyyy-MM-dd HH:mm:ss");
    double temp = lista[1].toDouble(&ok);
    if ( ok && dtObj.isValid()){
    vDT->append(dtObj);
    vV->append( temp );
    //Problemas con punteros cout << qPrintable( dtObj.toString("yyyy-MM-dd HH:mm:ss")) << " "<< vV[c] << endl;
    c++;
    } else {
    cerr << "Formato de fecha-hora o de punto flotante incorrecto en linea " << c+1 << endl;
    return(-2);
    }

    } else{
    cerr << "No hay dos columnas en linea " << c+1 << endl;
    return(-3);
    }
    linea = entra.readLine();
    }
    aEnt.close();

    return 0;
    }

    int main(int argc, char **argv)
    {
    QString sN = "pru384.txt";
    // QString sN = QString(argv[1]);
    QVector<QDateTime> vFechas;
    static QVector<double> vVal;

    leeVarMet( sN, &vFechas, &vVal );
    QApplication app(argc, argv);

    QwtPlot *grafScree = new QwtPlot();
    grafScree->setTitle("Grafico de Serie de Tiempo");
    // insertLegend(new QwtLegend(), QwtPlot::RightLegend);
    grafScree->setAxisTitle(QwtPlot::xBottom, "Tiempo");
    // grafScree->setAxisScale(QwtPlot::xBottom, 1,2, 0.1);
    // grafScree->setAxisMaxMinor(QwtPlot::xBottom,0);
    // grafScree->setAxisTitle(QwtPlot::yLeft, "Autovalores");

    // Preparando los valores de pru384.txt
    int longX = vVal.size();
    double *pY = vVal.data();
    double *pX = new double[longX];
    QDate fRef(2000, 1, 1);
    QTime tRef(0, 0, 0);

    for (int f = 0; f < longX; f++) {
    pX[f] = (double) fRef.daysTo(vFechas[f].date());
    pX[f] += tRef.secsTo(vFechas[f].time())/86400.0;
    // cout << pX[f]<< " " << pY[f] <<endl;
    }

    //
    QwtPlotCurve *autoVal = new QwtPlotCurve();
    autoVal->setData( pX, pY, 384);
    QwtSymbol sym;
    sym.setStyle(QwtSymbol::Star1);
    sym.setSize(4);
    sym.setPen(QColor(Qt::red));
    sym.setBrush(QColor(Qt::red));
    autoVal->setSymbol(sym);
    autoVal->setPen(QColor(Qt::black));
    autoVal->setStyle(QwtPlotCurve::Lines);
    autoVal->attach(grafScree);
    grafScree->resize(800,400);
    grafScree->show();
    // grafScree->replot();

    QwtPlotCanvas grafCanvas(grafScree );
    if ( grafCanvas.testPaintAttribute( QwtPlotCanvas::PaintCached ) ) cout << "PaintCached activado" << endl; else cout << "PaintCached desactivado" << endl;

    // grafCanvas.setPaintAttribute( QwtPlotCanvas::PaintCached, false);

    /* fjsoley@supergajo:~/grafiactual/prupixmap> ./prupixmap
    PaintCached activado
    No se creó el pixmap.*/


    QPixmap *pmGraf = grafCanvas.paintCache();
    if ( pmGraf->isNull() ) cout << "No se creó el pixmap."<<endl;
    if (pmGraf->isQBitmap() ) cout << "Es un bitmap."<<endl;
    // QImage imgGraf = pmGraf->toImage();
    // pmGraf->save("grafdin384.png", "PNG", -1);
    // cout << pmGraf;
    // fjsoley@supergajo:~/grafiactual/prupixmap> ./prupixmap | display
    // display: no decode delegate for this image format `/tmp/magick-XXj30Mz2'.
    //
    return app.exec();
    }

  2. #2
    Join Date
    Aug 2009
    Location
    San José, Costa Rica
    Posts
    4
    Qt products
    Qt4
    Platforms
    Unix/X11

    Question Re: Problem using QwtPlotCanvas::paintCache();

    Some additional information about paintCache().

    If the instruction
    QPixmap *pmGraf = grafCanvas.paintCache()
    works, is easy to stream the plot. The following code could do it:

    ***********
    <code>
    QPixmap *pmGraf = grafCanvas.paintCache();
    QImage image = pmGraf->toImage();
    QFile outputFile;
    if (!outputFile.open(stdout, QIODevice::WriteOnly))
    {
    cout << "outputFile did not open." <<endl;
    }
    QDataStream out(&outputFile);
    out << image;
    </code>
    **************
    If the output stream is redirected to a file,
    my_application >> redirected_file.png
    it can not be displayed. The reason is that
    the file consists of the image with 4 extra bytes appended at the beginning.
    If those 4 extra bytes are eliminated the image displays properly. I read a 16918 bytes
    PNG image and streamed it out using a similar code as above . The redirected file was 16943 bytes long and it displayed properly with

    tail -c 16939 redirectedfile.png | display


    In the Qwt documentation I could not find any explanation why paintCache() returns a NULL pixmap. If some one knows please let me know.

  3. #3
    Join Date
    Aug 2009
    Location
    San José, Costa Rica
    Posts
    4
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: solution for problem with paintCache()

    There is really no problem with QwtPlotCanvas::paintCache() .

    In my previous post I claimed having trouble using QwtPlotCanvas::paintCache() . Since this function is the only one that returns a QPixmap* in QwtPlotCanvas, I mistakenly assumed that this function is the one that fills the Pixmap with the contents of the plot. Studying the source files one finds that paintCache() only returns a pointer which may be NULL. And that is exactly what I was getting. As it turns out, the contents of the plot are grabbed in the function setPaintAttribute(), allthough the documentation only mentions that it changes the paint atrributes. Tried to use this function with no success, so I grabbed directly the contents.
    <code>
    const QRect qRC = grafScree->contentsRect();
    cerr << "Plot contents rectangle. "<< qRC.x()<< " "<< qRC.y()<< " "<<qRC.width()<<" "<<qRC.height()<<endl;

    // Create the PixMap
    QPixmap cache = QPixmap(qRC.width(), qRC.height() );

    if ( cache.isNull() ) cerr << "Pixmap not created."<<endl; else cerr << "Pixmap created."<<endl;
    // Fill the Pixmap with the plot
    cache = QPixmap::grabWidget(grafScree,
    qRC.x(), qRC.y(), qRC.width(), qRC.height() );
    //Also works: QPixmap cache = QPixmap::grabWindow(QApplication::desktop()->winId());
    </code>

    The whole idea of the exercise was to be able to stream to stdin the plot so that it will be piped to a second application thru stdin. The code to do it is:
    <code>
    // Change the Pixmap to an image that will be streamed out. (The Pixmap can be streamed out following the same procedure.)
    const QImage imSal = cache.toImage();

    QFile outputFile;
    if (!outputFile.open(stdout, QIODevice::WriteOnly))
    {
    cerr << "Outputfile not opened" <<endl;
    }
    QDataStream out(&outputFile);
    out << imSal;

    </code>
    It is important to remember that the output stream consists of the binary image with 4 bytes appended at the beginning. One easy way of getting rid of the first four bytes is using the tail command, For example, with
    ./streamplot | tail -c 10747 - | display
    a 10751 byte stream is trimmed by tail to the last 10747 bytes (the image) and displayed by display .
    The attachment contains streamplot.cpp , data file pru384.txt, the PNG image and the project file.:)
    Attached Files Attached Files

  4. #4
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,311
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Problem using QwtPlotCanvas::paintCache();

    The cache of the canvas is intended to speed up painting the content of the canvas for situations, where the content hasn't changed ( comparable to the backing store, but tailored for the situation of the Qwt framework ). But the cache is not intended for exporting the plot, what is pretty obvious as you will never see any axes.

    Instead you have to use QwtPlot::print what is a much more powerful solution ( even comparable to QPixmap::grabWidget() ) as you can create scalable vector graphics in formats like SVG or PDF.

    Uwe

Similar Threads

  1. Replies: 1
    Last Post: 23rd April 2009, 09:05
  2. Replies: 19
    Last Post: 3rd April 2009, 23:17
  3. Grid Layout Problem
    By Seema Rao in forum Qt Programming
    Replies: 2
    Last Post: 4th May 2006, 12:45
  4. Problem with receiving events from QDateEdit
    By gunhelstr in forum Qt Programming
    Replies: 4
    Last Post: 20th April 2006, 11:21
  5. fftw problem
    By lordy in forum General Programming
    Replies: 1
    Last Post: 16th March 2006, 21:36

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.