[Qt-interest] Problem drawning in the GUI Thread with Data from another Thread
O Caldas
caldaz.sheep at gmail.com
Fri Jul 3 02:49:24 CEST 2009
ive tyed this
void PopGraph::paintEvent(QPaintEvent*){
QPainter painter2(this);
buffer2 = buffer;
painter2.drawImage(QPoint(0,0), *buffer2);
}
and also tryed this
void PopGraph::paintEvent(QPaintEvent*){
QPainter painter2(this);
temp = buffer2;
buffer2 = buffer;
buffer = temp;
painter2.drawImage(QPoint(0,0), *buffer2);
}
and in the two methods the program still crashs
and btw, the calculation part is correct, the application only crash when is
drawning the graphic
2009/7/2 Malyushytsky, Alex <alex at wai.com>
> I am not sure I correctly followed your design.
> I assume graphUpdate is called from the working thread (through signal
> slot mechanics or directly).
> In this case you have to make sure graphUpdate is not running when
> painter2.drawImage(QPoint(0,0), *buffer);
> is executed.
> Otherwise for example buffer may be deleted when drawImage is still
> drawing. This means application crash or termination (well exception
> handling would be great any way).
>
> QMutex or other thread safety mechanics can be a friend here.
>
> The simplest approach would be to lock paintEvent and graphUpdate with
> mutex, but I would suggest to add some code make them actually run
> simultaneously, in order to allow graphUpdate to draw into its buffer while
> Widget is painting.
>
> In this case 2 buffers are required. One buffer is used to draw from the
> paintEvent. Another buffer is used by graphUpdate to draw into.
>
> Widget itself paints from the buffer any time it needs an update (no matter
> who caused the update).
> graphUpdate is always drawing into second buffer, but when it finish
> drawing and the image is ready to be shown, it swaps the buffers (it means
> just changing pointers) and then forces Widget update (through thread safe
> procedures, like Queued connection).
>
> You still will need to guard the pointers when swapping them and in the
> paintEvent, but this operations is very fast.
>
> Hope this helps,
> Alex
>
>
>
>
>
>
>
> From: qt-interest-bounces at trolltech.com [mailto:
> qt-interest-bounces at trolltech.com] On Behalf Of O Caldas
> Sent: Thursday, July 02, 2009 4:33 PM
> To: qt-interest at trolltech.com
> Subject: Re: [Qt-interest] Problem drawning in the GUI Thread with Data
> from another Thread
>
> oh, and here is the code of the paintEvent() method:
>
> void PopGraph::paintEvent(QPaintEvent*){
> QPainter painter2(this);
> painter2.drawImage(QPoint(0,0), *buffer);
>
> }
>
> buffer is an atribute QImage* of the class
> 2009/7/2 O Caldas <caldaz.sheep at gmail.com>
> 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
>
>
>
> --
> Daniel Mendes Caldas
>
>
>
> ---------------------------------------------------------------------------------------------------
> Weidlinger Associates, Inc. made the following annotations.
>
> "This message and any attachments are solely for the intended recipient and
> may contain confidential or privileged information. If you are not the
> intended recipient, any disclosure, copying, use, or distribution of the
> information included in this message and any attachments is prohibited. If
> you have received this communication in error, please notify us by reply
> e-mail and immediately and permanently delete this message and any
> attachments. Thank you."
>
> "Please consider our environment before printing this email."
>
> _______________________________________________
> 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/01bb718c/attachment.html
More information about the Qt-interest-old
mailing list