PDA

View Full Version : Adding item to GridLayout???



Kapil
4th April 2006, 05:47
Hi..

I have created a canvas and have given it a grid layout... Now i want to add items to it...

But the addItem() function takes a QLayoutItem to be added..
I want to add a Q3CanvasLine object to the first row and column but am not able to do so...

How do i do that.. i tried to create a QLayoutItem with a QCanvasLine object but it wasn't created.. what is the procedure to do it...

Thanking you,

with regards,
Kapil

munna
4th April 2006, 06:36
I don't think you can add a canvas item to a layout.

Kapil
4th April 2006, 06:43
I don't think you can add a canvas item to a layout.

But i was able to sucessfully set up grid layout for the canvas... and its returning the rowCount and columnCount as well...

can't there be any way in which i can typecast my canvasitem to layoutitem and then add it?????

wysota
4th April 2006, 09:15
No. Canvas doesn't work that way. It doesn't use layouts.

Kapil
4th April 2006, 09:26
No. Canvas doesn't work that way. It doesn't use layouts.

Aaahhhhhh:(

Thanks for the reply...

Is there any way to work like a layout works... i.e. while creating items i want them to specify them in a particular region.. like a rectangular region which would contain set of items independent from the other regions... i can work on these group of items in a particular rectangular region as a whole.. like moving the entire region to other part..
or like making a copy of the entire region and repeating it multiple times (like normal copy and paste types)...

is there any way out for this ?????

wysota
4th April 2006, 09:32
Try with an article on Qt Quarterly -- Canvas Item Groupies (http://doc.trolltech.com/qq/qq05-canvasitemgrouping.html).

Kapil
4th April 2006, 12:27
Hey...

Thanks a lot.. it was able to group similar elements together and now i can act on them as a whole single item...

One problem is still there.. to perform the copy and paste task, i.e. to create multiple instances of the object and then place them one after another on the canvas... what i did was that i copied the object information into another object and tried to place it.. but now it is just overwriting it on the current location.. now it contains the same pixel information and is overwriting it... How do i change that information to new location information ????

How do i perform the copy n paste task ???

Should i put in the code of mine which i wrote to perform the copy n paste to make it more clear????

wysota
4th April 2006, 13:36
One problem is still there.. to perform the copy and paste task, i.e. to create multiple instances of the object and then place them one after another on the canvas... what i did was that i copied the object information into another object and tried to place it.. but now it is just overwriting it on the current location.. now it contains the same pixel information and is overwriting it... How do i change that information to new location information ????
Maybe you should just... move it?


How do i perform the copy n paste task ???
I believe this topic is widely described in the documentation.

Kapil
4th April 2006, 13:50
Maybe you should just... move it?

moving it, shifts the group to some other part of the canvas... but does not replicate it...
i want to create many copies of it all over the place...

I went thru the doc carefully.. but it talked abt adding,moving,deleting, merging.... It tells me to create a group by clubbing the elemnts but does not tell me to recreate elements from that group at different location...

that is the problem which is there...

sorry, but any function of CanvasGroup class in the doc was not able to give me a bit of info on how to perform copy and paste on a group of elements...

Thanks,

Kapil

wysota
4th April 2006, 13:56
sorry, but any function of CanvasGroup class in the doc was not able to give me a bit of info on how to perform copy and paste on a group of elements...

I wasn't talking about canvas group. I was talking about clipboard mechanisms present in Qt. If you paste a group, you naturally have to make a copy of each element in it as new instances, make a new group and insert those elements in the group. All according to the mime information present in the clipboard object.

Kapil
4th April 2006, 14:47
hi..

i went through the documentation of QClipboard, QMimeData and QByteArray...
as per what i understood this is what i have to do..

CanvasGroup *canvasgp = new CanvasGroup;
//Then i create the entire group
QByteArray *barr = new QByteArray(1);
barr[0] = canvasgp;
QMimeData *mime = new QMimeData;
mime->setData("Canvas Group",&barr);
clipboard->setMimeData(mime,mode);

is this approach correct.. basically this is first time i am dealing with it and as well learning all these concepts as you know.. so i might seem to make disasterous mistakes as well..
sorry for asking you so many questions..

Thanks,
Kapil

wysota
4th April 2006, 15:12
Not quite correct. You should serialise the group into the byte array, not assign it.

For example let's assume you have an item CanvasItem which has properties such as its coordinates (x and y), dimensions (w and h) name (name) and colour (c). To serialise it, you could for example create such a function for it:


QDataStream & operator<<(QDataStream &ds, CanvasItem &item){
ds << "CanvasItem" << item.x << item.y << item.w << item.h << item.name << item.c;
return ds;
}

You can then provide a function for deserialisation too:


QDataStream & operator>>(QDataStream &ds, CanvasItem &item){
QString type;
ds >> type;
if(type!="CanvasItem"){
qDebug("Not a canvas item");
return;
}
ds >> item.x >> item.y >> item.w >> item.h >> item.name >> item.c;
}

Serialisation is a way to turn an object into its "text" or binary (stream in general) representation which can then be stored somewhere (for example piped through network). Deserialisation is something opposite -- creates objects out of their serial representation.

Then you'll be able to fill your QMimeData object:


CanvasItem *item;
//...
QByteArray ba;
QDataStream ds(&ba);
ds << *item;
QMimeData *mime = new QMimeData;
mime->setData("Canvas Group",&ba);
clipboard->setMimeData(mime,mode);
Of course you can do the same with the group. Serialise the whole group by providing some header from the group and then serialising all its elements (and maybe also provide some footer).

Kapil
5th April 2006, 12:43
Hi..

Thanks a lot for the reply and the code...
man it would take me ages :D to code it in such a nice manner :cool:

Small questions before i try out this way...


Serialise the whole group by providing some header from the group

header of the group here means the first element of the group or ????? same for footer ie the last element or ?????

then do i have to serialize each element from the group individually and then include it back in the group or i can send the entire group for getting serialized????

Also one doubt which was coming up again and again... It might be the stupidest of doubts but somehow was not able to figure it out...

How does this copy and paste here actually happens.. i went thru the QClipboard doc and the Canvas Group eg... for pasting i would have to make a copy of each element of the existing group into a new group... just like transferring info from one to another.. but that transfers the entire info abt the items ie the x,y coordinates, height and width and name..
now for pasting it to a new location, all this info for each item would change.. ie it would have a new x,y location in correspond to the pasting.. so will all these info get automatically changed or who will do it as per their new position????

Thanking you,

with regards
Kapil

wysota
5th April 2006, 13:29
header of the group here means the first element of the group or ????? same for footer ie the last element or ?????


Header of a group is something which will allow you to identify the group. In the simplest case it could be just a number of items in the group (so that you know how many times should you call the deserialisation). Footer is not necessary but it can help you spot that you reached the end of the group (if you don't provide the number of elements in the header).


then do i have to serialize each element from the group individually and then include it back in the group or i can send the entire group for getting serialized????

Group serialiser can call serialisation methods for all objects it contains:


QDataStream &operator <<(QDataStream &ds, CanvasGroup &gr){
ds << "CanvasGroup" << itemCount(); // header
for(int i=0;i<itemCount();i++) ds << *item(i); // items
ds << "End of canvas group"; // footer (not needed in this case)
return ds;
}


How does this copy and paste here actually happens.. i went thru the QClipboard doc and the Canvas Group eg... for pasting i would have to make a copy of each element of the existing group into a new group... just like transferring info from one to another.. but that transfers the entire info abt the items ie the x,y coordinates, height and width and name..
now for pasting it to a new location, all this info for each item would change.. ie it would have a new x,y location in correspond to the pasting.. so will all these info get automatically changed or who will do it as per their new position????

The object copied is represented by a block of data associated with some mime-type. It should contain all information about the object that should be transferred. When a drop (paste) happens the data is retrieved from the transfer object and the destination widget has to do something with it (for example create items which have the same attributes as those described by the data retrieved). It is your choice how to actually "insert" those objects to the destination widget. I would just "tilt" all items a little bit so that they don't cover original items -- for example by adding some small constant value to x and y (or just moving the group).

Kapil
5th April 2006, 14:16
Hi..

I have done as u said...

I created an object of Canvas Group i.e CanvasGroup *c_gp
Then i assigned it the canvas items...
Then i wrote the function of Serialization adn Deserialization as u told me to...

It then serialized my CanvasGroup object into a mime type...
After that i placed it on the Clipboard with setMimeData(mime,mode) function..

then i created another CanvasGroup Object i.e CanvasGroup *c_gp2;
then i retrieved back the mime data from the clipboard by the mimeData() func that returned me the mime data on clipboard...

Then i deserialized it and extracted the CanvasGroup object back... then running a loop i extracted each element of the CanvasGroup and created equal number of new Canvas Items with same info... then i assigned them to the new CanvasGroup object...

Here was where i am finding the problem...
now do i have to call the show() function of each of the canvasgroup items to paste them and then call the move function to move them at a new position ???????

wysota
5th April 2006, 15:13
I guess so:) At least if you want to make them visible. Did you have a look at drag&drop and clipboard examples that come with Qt?

Kapil
5th April 2006, 15:25
Did you have a look at drag&drop and clipboard examples that come with Qt?

I did have a look at the Drag and Drop example - Draagable Icons and Fridge Magnets ones..

What it said was that QDrag itself handles the drag and drop events...

i looked arnd for the ClipBoard example but couldnt get any...
where can i find it???>

Kapil
5th April 2006, 16:23
Hi...

I got a series of errors (sorry but i culdnt understand few of them :( )

Here is what i did:


CanvasGroup *m_pCanvasGp;
CanvasGroup *m_pCanvasGp2;
QMimeData *mime;
QMimeData *mime2;
QByteArray *ba;
QByteArray *ba2;
QClipboard *clipboard;

void ImageDraw::groupCanvasItems()
{
int i;
//Addition of the CanvasLines
for(i = 0;i<lineNum;i++)
{
m_pCanvasGp->add(m_pCanvasLine[i]);
}

//Addition of CanvasRectangles
for(i=0;i<recNum;i++)
{
m_pCanvasGp->add(m_pCanvasRectangle[i]);
}

QDataStream ds(*ba);
ds << *m_pCanvasGp;
mime->setData("Canvas Group",&ba);
clipboard->setMimeData(mime,QClipboard::Clipboard);
mime2 = clipboard->mimeData(mode);
ba2 = mime->data("Canvas Group");
QDataStream d2(*ba2);
ds2 >> *mpCanvasGp2;

}

QDataStream & operator<<(QDataStream &ds, CanvasGroup &cgp)
{
int i;
ds<<"Canvas Group"<<cgp.count();
for(i=0; i<cgp.count();i++)
ds << *(cgp.itemat(i));

return ds;
}

QDataStream & operator>>(QDataStream &ds, CanvasGroup &cgp)
{
int i;
QString type;
ds >> type;
if(type != "Canvas Group")
{
qDebug("Not a canvas group");
return;
}

ds >> *(cgp.itemat(i));
}


And these are the errors which i got


imagedraw.cpp: In member function `void ImageDraw::groupCanvasItems()':
imagedraw.cpp:80: error: no match for 'operator<<' in 'ds << *((ImageDraw*)this)
->ImageDraw::m_pCanvasGp'
C:/Qt/4.1.1/include/QtCore/../../src/corelib/io/qdatastream.h:119: note: candida
tes are: QDataStream& QDataStream::operator<<(qint8)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/io/qdatastream.h:192: note:
QDataStream& QDataStream::operator<<(quint8)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/io/qdatastream.h:121: note:
QDataStream& QDataStream::operator<<(qint16)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/io/qdatastream.h:195: note:
QDataStream& QDataStream::operator<<(quint16)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/io/qdatastream.h:123: note:
QDataStream& QDataStream::operator<<(qint32)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/io/qdatastream.h:198: note:
QDataStream& QDataStream::operator<<(quint32)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/io/qdatastream.h:125: note:
QDataStream& QDataStream::operator<<(qint64)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/io/qdatastream.h:201: note:
QDataStream& QDataStream::operator<<(quint64)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/io/qdatastream.h:127: note:
QDataStream& QDataStream::operator<<(bool)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/io/qdatastream.h:128: note:
QDataStream& QDataStream::operator<<(float)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/io/qdatastream.h:129: note:
QDataStream& QDataStream::operator<<(double)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/io/qdatastream.h:130: note:
QDataStream& QDataStream::operator<<(const char*)
C:/Qt/4.1.1/include/Qt3Support/../../src/qt3support/tools/q3glist.h:191: note:
QDataStream& operator<<(QDataStream&, const Q3GList&)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/tools/qchar.h:291: note:
QDataStream& operator<<(QDataStream&, const QChar&)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/tools/qbytearray.h:497: note:
QDataStream& operator<<(QDataStream&, const QByteArray&)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/tools/qstring.h:824: note:
QDataStream& operator<<(QDataStream&, const QString&)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/kernel/qobject.h:401: note:
QDebug operator<<(QDebug, const QObject*)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/kernel/qvariant.h:555: note:
QDataStream& operator<<(QDataStream&, const QVariant&)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/kernel/qvariant.h:557: note:
QDataStream& operator<<(QDataStream&, QVariant::Type)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/kernel/qvariant.h:650: note:
QDebug operator<<(QDebug, QVariant::Type)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/io/qurl.h:216: note:
QDataStream& operator<<(QDataStream&, const QUrl&)
C:/Qt/4.1.1/include/QtCore/../../src/corelib/io/qurl.h:221: note:
QDebug operator<<(QDebug, const QUrl&)
C:/Qt/4.1.1/include/QtGui/../../src/gui/widgets/qsplitter.h:127: note:
QTextStream& operator<<(QTextStream&, const QSplitter&)

imagedraw.cpp:81: error: no matching function for call to `QMimeData::setData(co
nst char[13], QByteArray**)'
C:/Qt/4.1.1/include/QtCore/../../src/corelib/kernel/qmimedata.h:63: note: candid
ates are: void QMimeData::setData(const QString&, const QByteArray&)

imagedraw.cpp:84: error: conversion from `QByteArray' to `QByteArray*' is ambigu
ous

C:/Qt/4.1.1/include/QtCore/../../src/corelib/tools/qbytearray.h:327: note: candi
dates are: QByteArray::operator const void*() const <near match>
C:/Qt/4.1.1/include/QtCore/../../src/corelib/tools/qbytearray.h:294: note:
QByteArray::operator QNoImplicitBoolCast() const <near match>
imagedraw.cpp:86: error: `mpCanvasGp2' undeclared (first use this function)
imagedraw.cpp: In function `QDataStream& operator<<(QDataStream&, CanvasGroup&)'
:
imagedraw.cpp: In function `QDataStream& operator>>(QDataStream&, CanvasGroup&)'
:
imagedraw.cpp:162: error: return-statement with no value, in function returning
'QDataStream&'
imagedraw.cpp:165: error: 'class CanvasGroup' has no member named 'itemat'
mingw32-make[1]: *** [debug\imagedraw.o] Error 1
mingw32-make[1]: Leaving directory `D:/Kapil_Folder/ViewChip/mousesetcanvas'
mingw32-make: *** [debug] Error 2


I am totally blown out and clueless...
Also checked the QDataStream for the operator functions but culdnt get the solution...:(

Kapil

wysota
5th April 2006, 17:56
Your code doesn't make much sense... where is "copy" and where is "paste" in it? You merged those two operations here... why?

As for the errors, the operator must be incorrectly defined.

Kapil
7th April 2006, 06:26
Aaahhh.. Okay... would try to recode the thing again...
As per the copy part of it then i thought this was the copy part ie setting the mime data in the clipboard copies it...


QDataStream ds(*ba);
ds << *m_pCanvasGp;
mime->setData("Canvas Group",&ba);
clipboard->setMimeData(mime,QClipboard::Clipboard);


And for pasting as u said

When a drop (paste) happens the data is retrieved from the transfer object and the destination widget has to do something with it (for example create items which have the same attributes as those described by the data retrieved).

I created another CanvasGroup object and tried to extract the data into it with the following set of commands i.e.


mime2 = clipboard->mimeData(mode);
ba2 = mime->data("Canvas Group");
QDataStream d2(*ba2);
ds2 >> *mpCanvasGp2;

This was my paste part... now i would have moved the newly created canvasgroup object to a new location to make it happen...

I exactly didnt merge them..it was just a prototype which i had developed to run the entire copy and paste process in the same function to check its validity... when implementing it in a real sense, i would part the two things...

For the operator errors, then i checked with the QDataStream class description and its functions... i just exactly did as per the code sample given by you.. i made no changes from my side..

Would try the thing again afresh... Would try to give it my best shot and disturb you the least.. you have really helped me in coming up with so many solutions.. had this forum not been there, i would have taken ages to do what i have done so far...
Thanks a lot for your help...

with regards,
Kapil

wysota
7th April 2006, 10:13
For the operator errors, then i checked with the QDataStream class description and its functions... i just exactly did as per the code sample given by you.. i made no changes from my side..
I didn't say they were absolutely correct. This is really a c++ issue of either overriding a class streaming operator or providing an external function which acts as one (so you can solve it by reading a C++ tutorial or a book). If you can't handle the second approach, try the first one.

Kapil
7th April 2006, 10:22
Ok... so i would try to inherit the class QDataStream and try to override the operator function...

About the copy paste concept, was my logic correct while applying it ???
Like the way i thought for doing it.. i might be syntactially wrong and would correct it if my approach is okay... so wanted to know is it right way to go for it ???

Kapil

wysota
7th April 2006, 11:24
Ok... so i would try to inherit the class QDataStream and try to override the operator function...
Nothing like that. Implement operator<< and operator>> in your class.



About the copy paste concept, was my logic correct while applying it ???
Like the way i thought for doing it.. i might be syntactially wrong and would correct it if my approach is okay... so wanted to know is it right way to go for it ???

If it works then it's fine. If it doesn't then it's not.

Kapil
7th April 2006, 11:26
If it works then it's fine. If it doesn't then it's not.

Thanks a lot.. ;)
That was a smart answer :cool: