PDA

View Full Version : Resources files (.qrc) not working



degs2k4
15th February 2008, 06:19
Hello,

I am porting a Qt3 Custom widget from qt3 to qt4, building a plugin for it. This custom widget uses 2 images, "butterfly.png" and "qtlogo.png":


MyCanvasView::MyCanvasView(QWidget *parent, const char *name )
: Q3CanvasView(parent,name) {

myCanvas = new Q3Canvas(800,600);
QColor c(0,0,255);//
myCanvas->setBackgroundColor ( c );//
myCanvas->setAdvancePeriod(30);
myCanvas->setDoubleBuffering(true);
this->setCanvas(myCanvas);
imageRTTI = 984376;
mainCount = 0;
butterflyimg = 0;
logoimg = 0;
tb = 0;
tp = 0;
QString butterfly_fn = ":/images/butterfly.png";
butterflyimg = new QImage[4];
butterflyimg[0].load( butterfly_fn );
butterflyimg[1] = butterflyimg[0].scaled(
int(butterflyimg[0].width()*0.75),
int(butterflyimg[0].height()*0.75) );
butterflyimg[2] = butterflyimg[0].scaled(
int(butterflyimg[0].width()*0.5),
int(butterflyimg[0].height()*0.5) );
butterflyimg[3] = butterflyimg[0].scaled(
int(butterflyimg[0].width()*0.25),
int(butterflyimg[0].height()*0.25) );
QString logo_fn = ":/images/qtlogo.png";
logoimg = new QImage[4];
logoimg[0].load( logo_fn );
logoimg[1] = logoimg[0].scaled( int(logoimg[0].width()*0.75),
int(logoimg[0].height()*0.75) );
logoimg[2] = logoimg[0].scaled( int(logoimg[0].width()*0.5),
int(logoimg[0].height()*0.5) );
logoimg[3] = logoimg[0].scaled( int(logoimg[0].width()*0.25),
int(logoimg[0].height()*0.25) );

}

void MyCanvasView::addButterfly()
{
Q3CanvasPolygonalItem* i = new ImageItem(butterflyimg[rand()%4],myCanvas);
i->move(rand()%(myCanvas->width()-butterflyimg->width()),
rand()%(myCanvas->height()-butterflyimg->height()));
i->setZ(rand()%256+250);
i->show();
}






. The image files are here: (project folder)/images/(image file)

The code of my resources.qrc file used in the plugin is:


<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>images/butterfly.png</file>
<file>images/qtlogo.png</file>
</qresource>
</RCC>

The make file (.pro file from the plugin project) includes the line of the resource file:


RESOURCES = resources.qrc

The plugin compiles, the c. widget appears in qtdesigner whith its methods and everything, it works.

I make a new project using this widget and I run it. The slots from the c. widget that do not need any resources work perfectly. But when I attempt to call the slots who need resources (images) to run, the images are not shown at all.

Why the images, correctly defined in the resources fil, are not being shown?

:eek:

ksqt
15th February 2008, 06:52
The only difference I see from what you have and what I did in something similar is:


<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix=""> <---------- here added prefix=""
<file>png/fit.png</file>
<file>png/normal.png</file>
<file>png/smaller.png</file>
<file>png/bigger.png</file>
<file>pics2.qm</file>
</qresource>
</RCC>

and in .pro file:


RESOURCES += xxxxx.qrc <------- +=

degs2k4
15th February 2008, 07:00
I have just tried that, it still doesn't work. The images are not displayed.

Thanks anyway.

triperzz
15th February 2008, 14:29
try adding Q_INIT_RESOURCES(your_file).qrc to your main.cpp i dont remember if thats the right code, just check it in qt assistant

degs2k4
18th February 2008, 23:20
Thanks for the reply, but it is not solved yet...

I am going to try to explain the problem in more detail:

I have a qt4-ported qt3 custom widget, and it uses images in 2 slots (addButterfly() adds a butterfly.png image; addLogo() adds a logo.png image). The widget compiles perfectly and the slots that don't use any images run perfectly. The slots that use images do not work at all.

I just want to be able to use those slots of the custom widget (and consequently the images inside of it ) in a new project.

So I put the line :


Q_INIT_RESOURCE(resources);
in the main.cpp file of the project which uses the ported custom widget.

and I add to the same project the file qrc_resources.cpp of the custom widget, generating a .o object.

But the images of the Custom widget are not shown.

I also tried to compile the resource file (.qrc) separately (with rcc) but no changes...:(

jacek
18th February 2008, 23:26
What does butterflyimg[0].load( butterfly_fn ) return?

degs2k4
19th February 2008, 12:23
Thanks for your reply.

I put, in the main of a new project, the code for loading the image of the custom widget and it returned true...

Perhaps it will be better to post here the files of the ported custom widget.

the zip contains all the necessary files of the ported custom widget (custom widget + plugin).

If you try to make a new project which uses this widget, you will see that slots like addLine() work, but methods like addButterfly() don't work:

sample code for the slots call in mainwinimpl.cpp:



//this works
void MainWindowImpl::on_pushButton_pressed()
{
mycanvasview->addLine();
}


//not working
void MainWindowImpl::on_pushButton_2_pressed()
{

mycanvasview->addButterfly();

}



sample code for the resources initalization from main.cpp:



int main(int argc, char ** argv)
{
Q_INIT_RESOURCE(resources);
QApplication app( argc, argv );
MainWindowImpl win;
win.show();
app.connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) );
return app.exec();
}


Thanks everyone. Your help here is absolutely priceless.

jacek
19th February 2008, 22:39
I put, in the main of a new project, the code for loading the image of the custom widget and it returned true...
Did you saw the image after that?

degs2k4
20th February 2008, 11:42
Did you saw the image after that?

No, I didn't.... :confused:

I think that the resource file is correctly added: I edited this line, adding an icon from the resource file:


QIcon MyCanvasViewPlugin::icon() const
{
return QIcon(":/images/qtlogo.png");
}

and this image appeared in QtDesigner on the WQidget Box next to the custom widget.

The load image function is also working fine, but calling the slot addButterfly() makes no effect when using the Q3CanvasPolygonalItem class.

UPDATE

the slot addButterfly() uses the class Q3CanvasPolygonalItem for displaying the image. I found this on the Internet:


The Q3CanvasPolygonalItem class provides a polygonal canvas item on a Q3Canvas. More...

#include <Q3CanvasPolygonalItem>

This class is part of the Qt 3 support library. It is provided to keep old source code working. We strongly advise against using it in new code. See Porting to Qt 4 for more information.

Note to Qt Desktop Light Edition users: This class is only available in the Qt Desktop Edition.

Maybe I should use the class QAbstractGraphicsShapeItem instead?

Any suggerences?

jacek
20th February 2008, 13:09
No, I didn't....
So maybe the resources work and the problem is in the code that displays the image?

What happens if you add:

QLabel l;
l.setPixmap( QPixmap( ":/images/butterfly.png" ) );
l.show();
just before return app.exec()?


Maybe I should use the class QAbstractGraphicsShapeItem instead?
No, you have to use Q3CanvasItem subclass, if you want to stick with Q3Canvas.

degs2k4
20th February 2008, 13:19
What happens if you add:
Qt Code:

QLabel l;
l.setPixmap( QPixmap( ":/images/butterfly.png" ) );
l.show();

just before return app.exec()?



If I do that, I can see the image !

So the problem is in addButterfly() slot then, right?

jacek
20th February 2008, 13:27
So the problem is in addButterfly() slot then, right?
Try showing Q3CanvasPixmap instead of your custom item.

What does ImageItem contructor do with the second parameter?

degs2k4
20th February 2008, 13:32
Try showing Q3CanvasPixmap instead of your custom item.

What does ImageItem contructor do with the second parameter?

Does this:


ImageItem::ImageItem( QImage img, Q3Canvas *canvas )
: Q3CanvasRectangle( canvas ), image(img)
{
setSize( image.width(), image.height() );
imageRTTI = 984376;
#if !defined(Q_WS_QWS)
pixmap.fromImage(image, Qt::OrderedAlphaDither);
#endif
}

jacek
20th February 2008, 19:59
Does this:
This looks OK (except that image and pixmap variables esentially hold the same data).

How does drawShape() implementation look like?

degs2k4
20th February 2008, 22:50
This looks OK (except that image and pixmap variables esentially hold the same data).

How does drawShape() implementation look like?

OK, the problem was with drawShape. drawShape() of ImageItem looked like this:



void ImageItem::drawShape( QPainter &p )
{
// On Qt/Embedded, we can paint a QImage as fast as a QPixmap,
// but on other platforms, we need to use a QPixmap.
#if defined(Q_WS_QWS)
p.drawImage( int(x()), int(y()), image, 0, 0, -1, -1, OrderedAlphaDither );
#else
p.drawPixmap( int(x()), int(y()), pixmap );
#endif
}

And I changed it to this:



void ImageItem::drawShape( QPainter &p )
{
// On Qt/Embedded, we can paint a QImage as fast as a QPixmap,
// but on other platforms, we need to use a QPixmap.
#if defined(Q_WS_WIN)
p.drawImage( int(x()), int(y()), image, 0, 0, -1, -1, Qt::OrderedAlphaDither );
#else
p.drawPixmap( int(x()), int(y()), pixmap );
#endif

}

And the butterfly was at last displayed !

So the problem is with Q_WS_QWS (maybe because it is from Qtopia?): used for detecting the type of windowing system that is used with Qt. Correspondingly there exist Q_WS_X11 and Q_WS_WIN that are set when compiling with Qt/X11 or Qt/Windows (and there's one
for mac in Qt3 versions).

Of course I can't just remove the macro that easily.... Why it didn't work when using Q_WS_QWS? It is OK to use Q_WS_X11, Q_WS_WIN... instead?

(I'm using windows...)

jacek
21st February 2008, 00:56
The problem is ImageItem::ImageItem(). It should be:
pixmap = QPixmap::fromImage(image, Qt::OrderedAlphaDither);

degs2k4
21st February 2008, 09:54
The problem is ImageItem::ImageItem(). It should be:
pixmap = QPixmap::fromImage(image, Qt::OrderedAlphaDither);

OH!!!! I see:

The Qt3 version was returning a BOOL ! :

bool QPixmap::convertFromImage ( const QImage & image, ColorMode mode )

and the Qt4 version is returning the Pixmap which I have to grab explicitely !

QPixmap QPixmap::fromImage ( const QImage & image, Qt::ImageConversionFlags flags = Qt::AutoColor )

THANKS!!!!!!!!!!!!!!!!!!!!!!!!!!!:)