[Qt-interest] Problem drawning in the GUI Thread with Data from another Thread

O Caldas caldaz.sheep at gmail.com
Fri Jul 3 01:31:07 CEST 2009


hi, my application draws a horizontal graphics of the data generated by the
thread. it uses vectors that are directly modified by the worker thread. ive
tryed to send the vectors in the signal but it stays the same.

here is the code that create the image that will be draw :

void PopGraph::graphUpdate(){
    delete(buffer);
    buffer = new QImage(size(), QImage::Format_ARGB32);
    QSize d = size();
    long long nMax = (int)ceil(log10(_d->getPopulationMax()));
    double yscale = d.height()/(double)nMax;
    int tickscale = 1;

    // draw horizontal tick marks
    Qt::PenStyle style = Qt::PenStyle(Qt::SolidPattern);
    Qt::PenCapStyle cap = Qt::PenCapStyle(Qt::FlatCap);
    Qt::PenJoinStyle join = Qt::PenJoinStyle(Qt::MiterJoin);
    QPainter painter(buffer);
    painter.fillRect(rect(), Qt::white);

    painter.setPen(QPen(Qt::black, 1, style ,cap,join));
    for (int i=0; i<=nMax; i++) {
        int y = size().height()-(int)(i*yscale);
        painter.drawLine(0, y, d.width(), y);
        char st[6] = "10^";
        strcat(st, intToStr(i));
        painter.drawText(0, y, QString(st));//("10^" + String.valueOf(i), 0,
y);
    }
    // draw vertical (date) tick marks
    long long lastday = -1;
    vector<long long> hours = _d->getPopulationHours();
    int end = d.width();
    if (hours.size()<d.width())
        end = hours.size();
    for (int i=0; i<end; i++) {
        if (lastday != hours[hours.size()-i-1]/24) {
            lastday = hours[hours.size()-i-1]/24;
            painter.drawLine(d.width()-i, 0, d.width()-i, d.height());
            painter.drawText(d.width()-i+1, 11, QString(
intToStr(lastday+1)));
        }
    }
    // draw antigen level curves
    vector<Antigen*>* pops = _d->getAntigens();
    vector<QColor> popcolors = _d->getAntigenColors();
    int s = _d->getAntigenLevels().size();

    for (int j=0; j<s; j++) {
        painter.setPen(popcolors[j]);
        // draw legend
        painter.drawText(0,
painter.fontMetrics().ascent()*(j+1),QString(pops->at(j)->getName()->data()));

        // draw curves
        vector< long long > data = _d->getAntigenLevels()[j];
        end = d.width();
        if (data.size()<(unsigned )d.width())
            end = data.size();
        for (int i=0; i<end; i+=2)  // just plot every other hour
            if (data[data.size()-i-1]>0){

                painter.drawRect(d.width()-i-1,
                        d.height()-1-(int)
                        (log10(data[data.size()-i-1])*yscale),
                        2,
                        2);
            }
    }
    // draw T cell level curves
    s = _d->getTCellColors().size();
    for (int j=0; j<s; j++) {
        painter.setPen(_d->getTCellColors()[j]);
        // draw legend
        if (_d->getTCells()->size()<10)
            painter.drawText(0,
painter.fontMetrics().ascent()*(j+1+(_d->getAntigens()->size())),
QString(_d->getTCells()->at(j)->getName()->data()));
        // draw curves
        vector<long long> data = _d->getTCellLevels()[j];
        end = d.width();
        if (data.size()<(unsigned )d.width()) end = data.size();
        for (int i=0; i<end-1; i++){
            if ((data[data.size()-i-1]>0) && (data[data.size()-i-2]>0)){
                painter.drawLine(d.width()-i-1,
                        d.height()-(int)
                        (log10(data[data.size()-i-2])*yscale),
                        d.width()-i,
                        d.height()-(int)
                        (log10(data[data.size()-i-1])*yscale));

            }
        }

    }
//    if(contador == 1){
//        contador =0;
        update();

//    }

}

thanks for your help!

2009/7/2 Sean Harmer <sean.harmer at maps-technology.com>

> On Thursday 02 Jul 2009 06:27:05 O Caldas wrote:
> > Hi, im working on a project where I have two threads, one Worker thread,
> > that do some calculations,
> > and one GUI Thread, that draw some graphics in a QWidget.
> >
> > The Worker thread is a class that inherits from QThread, and the GUI
> Thread
> > is the main thread obviously.
> >
> > Im geting the worker thread to send a signal every end of calculation
> step,
> > and connecting this signal
> > to the method that draws the graphic in the GUI Thread
> >
> > like this:
> >
> > connect(calculator, SIGNAL(calculated(),this,
> >             SLOT(updateView()));
> >
> > The problem is, when the calculation gets to fast, the GUI thread just
> bugs
> > and the program terminates.
> > It seems that the calculator thread starts sending too much signals and
> the
> > GUI thread cant handle it,
> > or something like this.
> >
> > i've tryed to use Qt::BlockingQueuedConnection but it is too slow.
> >
> > if someone knows what im doing wrong, or the right way to build a program
> > like that please help!
> It sounds like you are taking the right general approach. What does your
> app
> have to do in order to visualise the results? How do you get the data to
> the
> main thread as I notice your signal does not marshall any data across to
> it?
>
> If the visualisation in the main thread really is very expensive to perform
> then maybe you should only visualise every n'th frame. You could maybe make
> this an option that the user can set depending upon the performance of
> their
> graphics subsystem.
>
> Sounds like you have identified the bottle neck in your app. If you provide
> some more information we might be able to help you improve it.
>
> Cheers,
>
> Sean
>
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at trolltech.com
> http://lists.trolltech.com/mailman/listinfo/qt-interest
>



-- 
Daniel Mendes Caldas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20090702/c6da78d3/attachment.html 


More information about the Qt-interest-old mailing list