开发者

QGraphicsItem subclass throwing X Error and crashing

I am trying to create a QGraphicsItem that will pull data from a file in a threaded fashion, and display it when the data has been read in. Behold the code:

#ifndef TILE_H
#define TILE_H

#include <QGraphicsItem>
#include <QThread>
#include <QFutureWatcher>
#include <QtConcurrentRun>
#include "gdal_priv.h"
#include <QPainter>

class Tile : public QObject, public QGraphicsItem
{
    Q_OBJECT
    Q_INTERFACES(QGraphicsItem)

public:
    Tile(QGraphicsItem *parent = 0);

    Tile( int nBlocksX, int nBlocksY, int xoffset, int yoffset, int nXBlockSize, int nYBlockSize, int A_BPP,QGraphicsItem *parent=0);
    ~Tile();
    void LoadTilePixmap();

protected:
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget);
    QRectF boundingRect() const;

private:
    QFutureWatcher<void> *watcher;
    QFuture<void> *future;
    QImage *image;
    const QStyleOptionGraphicsItem *TileOption;
    QPainter *TilePainter;
    QWidget *TileWidget;
    int nBlocksX, nBlocksY, nBlockXSize, nBlockYSize, tilePosX, tilePosY, A_BPP;

signals:

public slots:
    void updateSceneSlot();

};

#endif // TILE_H

And the .cpp

#include "tile.h"

Tile::Tile(QGraphicsItem *parent) : QGraphicsItem(parent)
{
}

Tile::~Tile()
{
}
Tile::Tile(int nBlocksX, int nBlocksY, int xoffset, int yoffset, int nXBlockSize, int nYBlockSize, int A_BPP,QGraphicsItem *parent)
    : QGraphicsItem(parent)
{
//set some flags and size parameters related to reading from the file on disk. All instances of this QGraphicsItem read from the same file
    this->nBlocksX = nBlocksX;
    this->nBlocksY = nBl开发者_Python百科ocksY;
    this->nBlockXSize = nXBlockSize;
    this->nBlockYSize = nYBlockSize;
    this->tilePosX =xoffset;
    this->tilePosY = yoffset;
    this->A_BPP = A_BPP;
    setCacheMode(NoCache);
    setFlag(QGraphicsItem::ItemIsMovable,false);
    setActive(true);
    this->setAcceptHoverEvents(true);
    this->setFlag(QGraphicsItem::ItemIsFocusable);
    this->image = NULL;

    this->future = new QFuture<void>;
    this->watcher = new QFutureWatcher<void>;
    connect(watcher,SIGNAL(finished()),this,SLOT(updateSceneSlot()));
}
QRectF Tile::boundingRect() const
{
    if(image == NULL)
        return(QRectF(0,0,0,0));

    return(QRectF(0,0,image->width(),image->height()));
}

void Tile::updateSceneSlot()
{
    qDebug("updateSceneSlot Thread id %i", QThread::currentThread());
    this->paint(TilePainter, TileOption, TileWidget);
}

void Tile::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)
{
    if(image==NULL)
    {
        TilePainter=painter;
        TileOption=option;
        TileWidget=widget;
        qDebug()<<"Paint Thread id "<< QThread::currentThread();
        *future=QtConcurrent::run(this, &Tile::LoadTilePixmap);
        watcher->setFuture(*future);

    }

    QPointF *p = new QPointF(0.0,0.0);
    painter->drawImage(*p, *image);
}

void Tile::LoadTilePixmap()
{
 /*...populate floatData with data from file...*/

    image = new QImage(nXSize, nYSize, QImage::Format_RGB32);
        for (int i = 0 ; i < nYSize ; i++)
        {
             for (int j = 0 ; j < nXSize ; j++)
             {
                    image->setPixel(j,i,qRgb((unsigned char)floatData[i*nXSize+j],(unsigned char)floatData[i*nXSize+j],(unsigned char)floatData[i*nXSize+j]));
             }
         }


}

This will compile fine,but when I try to load an image, i get a whole bunch of X errors, and the program quits:

.
.
.
X Error: BadGC (invalid GC parameter) 13
  Major opcode: 60 (X_FreeGC)
  Resource id:  0x1c002bb
X Error: RenderBadPicture (invalid Picture parameter) 181
  Extension:    156 (RENDER)
  Minor opcode: 7 (RenderFreePicture)
  Resource id:  0x1c002ba
X Error: BadPixmap (invalid Pixmap parameter) 4
  Major opcode: 54 (X_FreePixmap)
  Resource id:  0x1c002b9
X Error: BadAlloc (insufficient resources for operation) 11
  Major opcode: 53 (X_CreatePixmap)
  Resource id:  0x1c002bc
X Error: BadDrawable (invalid Pixmap or Window parameter) 9
  Extension:    156 (RENDER)
  Minor opcode: 4 (RenderCreatePicture)
  Resource id:  0x1c002bc
X Error: BadDrawable (invalid Pixmap or Window parameter) 9
  Major opcode: 55 (X_CreateGC)
  Resource id:  0x1c002bc
X Error: BadGC (invalid GC parameter) 13
  Major opcode: 56 (X_ChangeGC)
  Resource id:  0x1c002be
X Error: BadDrawable (invalid Pixmap or Window parameter) 9
  Major opcode: 70 (X_PolyFillRectangle)
  Resource id:  0x1c002bc
X Error: BadGC (invalid GC parameter) 13
  Major opcode: 60 (X_FreeGC)
  Resource id:  0x1c002be
X Error: RenderBadPicture (invalid Picture parameter) 181
  Extension:    156 (RENDER)
  Minor opcode: 7 (RenderFreePicture)
  Resource id:  0x1c002bd
X Error: BadPixmap (invalid Pixmap parameter) 4
  Major opcode: 54 (X_FreePixmap)
  Resource id:  0x1c002bc
Paint Thread id  QThread(0x105feac0) 
The program has unexpectedly finished.

What am I doing wrong? When I had this set up single-threaded, I was able to do this no problem.


Your image loading code is not thread-safe as QImage is not thread-safe. That should be the reason for your crashes.

You also have leaks, like the QPoint created on the heap and never deleted, in paint(). Just create it on the stack instead of the heap. Same for the image: You leak it, no need to create QImage's on the heap either. (they are implicitely shared so copies are cheap).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜