PDA

View Full Version : QImage * to QIcon



Diath
23rd December 2010, 18:33
Hey there.

I have array of custom structure object called Sprite, it looks like this:

struct Sprite
{
Sprite() { image = new QImage(32, 32, SPRITE_FORMAT); }
void setSprite(QImage *inImage) { image = inImage; }
QImage *getSprite() { return image; }

QImage *image;
uint8_t width, height, r, g, b;
};

Now, I have QListWidget and I'd like to insert items with icons from that array, but I have problem. QPixmap::fromImage takes &QImage as parameter, and my function (getSprite()) returns pointer.

I have following code (which crashes):

foreach(Item *x, ItemsLoader->xmlMap)
{
QListWidgetItem *item = new QListWidgetItem;

QString itemText = x->getName();
itemText = itemText.left(1).toUpper() + itemText.mid(1);
item->setText(itemText + " (ID: " + QString::number(x->getId()) + ")");

Sprite *sprite = ItemsLoader->sprMap[x->getId()];
item->setIcon(QIcon(QPixmap::fromImage(*sprite->getSprite())));

ui->ItemsListWidget->addItem(item);
}

I guess following line is causing application crash:

item->setIcon(QIcon(QPixmap::fromImage(*sprite->getSprite())));

How do I convert correctly from QImage* to &QImage?

Lykurg
23rd December 2010, 18:51
Hi, use
item->setIcon(QIcon(QPixmap::fromImage(*(sprite->getSprite()))));Otherwise you dereference sprite! But anyway, this code is hardly readable. Use temporary variables, thus you can maintain your code. And most compilers will optimize them away, to there should be no speed/performance impact.

Diath
23rd December 2010, 19:00
Umm, still crashes. I tried to assign sprite->getSprite() to another variable to check if getSprite() doesn't cause crash and it doesn't so imho. it's still issue with converting.

Lykurg
23rd December 2010, 19:15
then debug if in that case the returned pointer is valid. Also can you submit a backtrace of the the crash.

Diath
23rd December 2010, 19:25
Not sure if that's what you meant, but there you have backtrace:


Thread 5 (thread 3864.0x1284):
#0 0x76e464f4 in ntdll!LdrFindResourceEx_U () from C:\Windows\system32\ntdll.dll
#1 0x76e44c3c in ntdll!ZwDeleteValueKey () from C:\Windows\system32\ntdll.dll
#2 0x751a1876 in SleepEx () from C:\Windows\system32\KernelBase.dll
#3 0x00000000 in ?? ()

Thread 4 (thread 3864.0xa78):
#0 0x76e5566e in ntdll!RtlAddAttributeActionToRXact () from C:\Windows\system32\ntdll.dll
#1 0x76e30c3f in ntdll!RtlGetCurrentPeb () from C:\Windows\system32\ntdll.dll
#2 0x76edcd38 in ntdll!NtAlertResumeThread () from C:\Windows\system32\ntdll.dll
#3 0x76e30bd3 in ntdll!RtlGetCurrentPeb () from C:\Windows\system32\ntdll.dll
#4 0x7e17f060 in ?? ()
#5 0x00000000 in ?? ()

Thread 3 (thread 3864.0xd60):
#0 0x76e464f4 in ntdll!LdrFindResourceEx_U () from C:\Windows\system32\ntdll.dll
#1 0x76e45e9c in ntdll!ZwYieldExecution () from C:\Windows\system32\ntdll.dll
#2 0x76e306ab in ntdll!RtlLargeIntegerShiftLeft () from C:\Windows\system32\ntdll.dll
#3 0x75a71194 in KERNEL32!AcquireSRWLockExclusive () from C:\Windows\system32\kernel32.dll
#4 0x76e5b495 in ntdll!RtlInsertElementGenericTableAvl () from C:\Windows\system32\ntdll.dll
#5 0x76e5b468 in ntdll!RtlInsertElementGenericTableAvl () from C:\Windows\system32\ntdll.dll
#6 0x00000000 in ?? ()

Thread 2 (thread 3864.0x16b4):
#0 0x76e464f4 in ntdll!LdrFindResourceEx_U () from C:\Windows\system32\ntdll.dll
#1 0x76e45e6c in ntdll!ZwWriteRequestData () from C:\Windows\system32\ntdll.dll
#2 0x76e2ef56 in ntdll!RtlIsValidIndexHandle () from C:\Windows\system32\ntdll.dll
#3 0x75a71194 in KERNEL32!AcquireSRWLockExclusive () from C:\Windows\system32\kernel32.dll
#4 0x76e5b495 in ntdll!RtlInsertElementGenericTableAvl () from C:\Windows\system32\ntdll.dll
#5 0x76e5b468 in ntdll!RtlInsertElementGenericTableAvl () from C:\Windows\system32\ntdll.dll
#6 0x00000000 in ?? ()

Thread 1 (thread 3864.0x15e4):
#0 0x0066b515 in QImage::convertToFormat (this=0x22fcc0, format=QImage::Format_RGB32, flags={i = 0}) at image\qimage.cpp:3747
#1 0x006915ce in QRasterPixmapData::createPixmapForImage (this=0xbe7cc48, sourceImage=@0x22fcc0, flags={i = 0}, inPlace=false) at image\qpixmap_raster.cpp:453
#2 0x006906b5 in QRasterPixmapData::fromImage (this=0xbe7cc48, sourceImage=@0x22fd18, flags={i = 0}) at image\qpixmap_raster.cpp:152
#3 0x006862ab in QPixmap::fromImage (image=@0x22fd18, flags={i = 0}) at image\qpixmap.cpp:2031
#4 0x00402297 in QMapEditor::startup (this=0x93b92b8) at ..\QMapEditor\qmapeditor.cpp:99
#5 0x00401876 in QMapEditor (this=0x93b92b8, parent=0x0) at ..\QMapEditor\qmapeditor.cpp:25
#6 0x004013ac in qMain (argc=1, argv=0x93b3688) at ..\QMapEditor\main.cpp:8
#7 0x00404a0a in WinMain@16 (instance=0x400000, prevInstance=0x0, cmdShow=10) at qtmain_win.cpp:131
#8 0x004047d2 in main ()

ChrisW67
24th December 2010, 00:06
I guess following line is causing application crash:

item->setIcon(QIcon(QPixmap::fromImage(*sprite->getSprite())));

Why guess? Single step through the code and determine exactly where the crash is and what the value of the various pointers is. Can ItemsLoader->sprMap[x->getId()] ever return something that is NULL or invalid, i.e. if x->getId() is not in the map?

Something for later: What happens to the QImage you allocate on the heap in the constructor when you setSprite() the first time?

Diath
24th December 2010, 09:35
I've added yesterday simple check if sprite or sprite->getSprite is NULL, like this:

if(sprite == NULL || sprite->getSprite() == NULL)
continue;

But it didn't help, application still crashes on item->setIcon~.

I can assign sprite->getSprite() to variable thought.

QImage *image = sprite->getSprite();

Really no idea what should I do.

@Edit:
I've tried to image->save() and output file is 0kb, seems like my function for reading sprites from file is failing somewhere - gotta fix that, thanks for all your help.

adam.ros
3rd January 2011, 18:49
Hi.
I do not know whether it is correct but try:

QImage *image = qobject_cast<QImage*>(sprite->getSprite());

and:

item->setIcon(QIcon(QPixmap::fromImage(image)));