Results 1 to 13 of 13

Thread: Streaming custom QVariant?

  1. #1
    Join Date
    Feb 2006
    Location
    US
    Posts
    173
    Thanks
    16
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Streaming custom QVariant?

    Hello,

    How do you stream a custom QVariant? I'm getting an error when using QDataStream to output to a binary file. Error is noted in code below.

    Where does the type (i.e. QVariant::Type) get specified? Is this done automatically by Q_DECLARE_METATYPE? I was trying to declare my own value (beyond QVariant::UserType), but I couldn't see where to accomplish it. It appears to just be set by defualt to QVariant::UserType, but I need multiple custom types.

    I'm hoping to leverage the Qt serialization capabilities ... handling byte-order, string length, etc.

    Qt Code:
    1. QDataStream & operator<<(QDataStream & out, const sStatePacket & record)
    2. {
    3. QVariant variant;
    4. variant.setValue(record);
    5. out << variant; // ERROR OCCURS HERE!!!
    6. return out;
    7. }
    8.  
    9. QDataStream & operator>>(QDataStream & in, sStatePacket & record)
    10. {
    11. QVariant variant;
    12. in >> variant;
    13. record.time = variant.value<sStatePacket>().time;
    14. record.pos = variant.value<sStatePacket>().pos;
    15. record.hpr = variant.value<sStatePacket>().hpr;
    16. return in;
    17. }
    18.  
    19. struct sStatePacket
    20. {
    21. float time;
    22. sPosRecord pos;
    23. sRotRecord hpr;
    24. };
    25. Q_DECLARE_METATYPE(sStatePacket)
    To copy to clipboard, switch view to plain text mode 

    Thank you,
    Ben

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Streaming custom QVariant?

    Is there a particular reason why you want to go through QVariant? Why not stream the data directly?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Feb 2006
    Location
    US
    Posts
    173
    Thanks
    16
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Streaming custom QVariant?

    If I use QVariant, I can leverage Qt's serialization and introspection capability. I can inspect what type the data is when I read it back using QVariant::type(). For example, I might have a binary file that has varying record types (not in any particular order).

    Here's a potential code snippet:
    Qt Code:
    1. void cLogStream::seek(float time)
    2. {
    3. QVariant variant;
    4. this->device()->seek(0);
    5. ...
    6. while(this->device()->atEnd() == false)
    7. {
    8. *this >> variant;
    9. if(variant.type() == sStatePacketType)
    10. {
    11. sStatePacket statePacket = variant.value<sStatePacket>();
    12. if(statePacket.time ...)
    13. mBuffer.push_back(variant);
    14. }
    15. ...
    16. }
    17. }
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Streaming custom QVariant?

    The problem is QVariant doesn't know how to serialize your custom type. It could serialize it as a byte array but it would have nothing to do with portability. If you need something like that then do it exactly this way - store the data as a byte array. Of course you will still have problems how to detect that a particular byte array is of your type, but this is achievable if you hand write the code.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Feb 2006
    Location
    US
    Posts
    173
    Thanks
    16
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Streaming custom QVariant?

    So, does Qt not support serialization of custom types?

    As long as the type is registered (using the macros, template functions, and stream operators), I would think that it would be able to properly serialize any object. Other serialization libraries do this. They output "header" information for each type ... just like is done with a QString where it writes QVariant::String, string length, then the string character data.

    The key is to make sure that the Variant::Type maps appropriately ... from when written to when read back. If the type isn't found, the header information should contain the size, so that it could be skipped ... incrementing the stream to the next record.

    Are you sure there is no serialization support? I'm very surprised. In fact it's a bit of a show-stopper!
    Last edited by brcain; 22nd May 2009 at 00:18.

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Streaming custom QVariant?

    Quote Originally Posted by brcain View Post
    So, does Qt not support serialization of custom types?
    It does but not through QVariant. You can (de)serialize an object and then place it into the variant.

    Other serialization libraries do this.
    Other serialization libraries are not portable or they have full introspection (such as java).

    They output "header" information for each type ... just like is done with a QString where it writes QVariant::String, string length, then the string character data.
    Qt does it the same way. But the header for QVariant can't possibly contain every information to recreate every possible structure in the world. That's why you provide your own implementation of streaming to data stream operator.

    Are you sure there is no serialization support? I'm very surprised. In fact it's a bit of a show-stopper!
    I'm just saying you should not go through QVariant. You might have noticed there is no streaming operator for QVariant, only a constructor that takes a reference to datastream to deserialize an object into the variant.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Feb 2006
    Location
    US
    Posts
    173
    Thanks
    16
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Streaming custom QVariant?

    Maybe I'm confusing QVariant with a meta-type of some sort. It seems to behave like one.

    So, for example, when reading a binary file of various custom types, how would one inspect what the record actually is? Qt's serialization would have to support this. Something has to handle the data as a generically sized "block" for the streaming to work. Otherwise, wouldn't know how to iterate through the binary file.

    BTW, I realize that QVariant (on its own) can't recreate every possible structure in the world, but through template-programming was thinking it should be able reconstruct any type (from the type identifier in the header). It (or at least the meta-type system) already has type knowledge through the registration mechanism. And, it (stream class) could skip/report unkown types (again by inspecting header information).

    The documentation (that I've come across) is limited on serialization. Do you have anything you'd recommend? Seems like it would be a great tutorial (maybe it is).

    BTW, thanks for your help ... appreciate it.
    Last edited by brcain; 22nd May 2009 at 01:50.

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Streaming custom QVariant?

    Quote Originally Posted by brcain View Post
    So, for example, when reading a binary file of various custom types, how would one inspect what the record actually is? Qt's serialization would have to support this. Something has to handle the data as a generically sized "block" for the streaming to work. Otherwise, wouldn't know how to iterate through the binary file.
    QDataStream is a low level mechanism. You want a high level one thus you have to use this low level mechanism to implement a high level mechanism. Simply speaking, if you want to detect what is the type of data in the stream, stream additional data that will let you detect the type. You can stream the name of the type, for example.

    Qt Code:
    1. QDataStream stream(...);
    2. QString str;
    3. stream << "string" << str;
    4. ...
    5. QDataStream inStream(...);
    6. QString type;
    7. stream >> type;
    8. if(type=="string"){
    9. stream >> s;
    10. var.setValue(s);
    11. }
    To copy to clipboard, switch view to plain text mode 

    You can use QMetaType to have automatic coversion of the type id to the name of the type to avoid unnecessary comparisons like in my code above.


    BTW, I realize that QVariant (on its own) can't recreate every possible structure in the world, but through template-programming was thinking it should be able reconstruct any type (from the type identifier in the header).
    I'm not sure how templates would be helpful here. QVariant is a class on its own, you don't create a new "QVariant" class in each application that uses Q_DECLARE_METATYPE.

    The documentation (that I've come across) is limited on serialization. Do you have anything you'd recommend? Seems like it would be a great tutorial (maybe it is).
    The only relevant docs are in QDataStream reference. This is really a marginal topic in Qt.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. #9
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Streaming custom QVariant?

    See [WIKI]Using custom data types with Qt[/WIKI].
    J-P Nurmi

  10. #10
    Join Date
    Feb 2006
    Location
    US
    Posts
    173
    Thanks
    16
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Streaming custom QVariant?

    Quote Originally Posted by wysota View Post
    QDataStream is a low level mechanism. You want a high level one thus you have to use this low level mechanism to implement a high level mechanism. Simply speaking, if you want to detect what is the type of data in the stream, stream additional data that will let you detect the type. You can stream the name of the type, for example.
    Thanks again. And I hope I don't sound too critical/whiney ...

    This seems like standard serialization framework support that should already exist. Maybe I misread what serialization support is actually there. The reason for serialization is so that you don't have to handle the meta-type information that is wrapped around the user type ... but are rather given the meta-type information that you can cast (from some data buffer) to what actually type is.

    Shouldn't serialization framework automatically handle Qt types and provide mechanism for custom types? I do override the QDataStream streaming operators, but that doesn't say anything about the header (type, size, etc.) that should be handled automatically.

    I can punt on this / quit beating a dead horse ... am just very surprised.

  11. #11
    Join Date
    Feb 2006
    Location
    US
    Posts
    173
    Thanks
    16
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Streaming custom QVariant?

    So, how do you stream from a binary file of varying types in non-deterministic order using QDataStream?

    Can you even do this with pre-defined Qt types?

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Streaming custom QVariant?

    Quote Originally Posted by brcain View Post
    Shouldn't serialization framework automatically handle Qt types and provide mechanism for custom types?
    It does. But not through QVariant

    I do override the QDataStream streaming operators, but that doesn't say anything about the header (type, size, etc.) that should be handled automatically.
    That's your task in the implementation of the operator.

    QDataStream is a mechanism do stream binary data to/from a device. It is not a general-purpose serialization mechanism but it can be used to create one. It's main task is to provide a way to store (and retrieve) binary data in some well known internal data format where you know what data you expect.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  13. #13
    Join Date
    Feb 2006
    Location
    US
    Posts
    173
    Thanks
    16
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Streaming custom QVariant?

    Quote Originally Posted by wysota View Post
    QDataStream [...] is not a general-purpose serialization mechanism but it can be used to create one.
    Okay, I think I finally get it. I read too much into the serialization support.

    A serialization framework would be a great future capability. It could be used for binary file streams as well as network streams, etc. ... as a tidey way to packetize all records.

    Much thanks,
    Ben

Similar Threads

  1. Convert between a custom data type wrapped in a QVariant
    By darkadept in forum Qt Programming
    Replies: 2
    Last Post: 17th March 2009, 09:07
  2. Getting Microsoft Word Object to SaveAs
    By jvwebb in forum Newbie
    Replies: 3
    Last Post: 2nd September 2008, 19:27
  3. How to convert QVariant to my custom object?
    By troorl_ua in forum Qt Programming
    Replies: 3
    Last Post: 15th July 2007, 18:59
  4. Treeview and custom model
    By steg90 in forum Qt Programming
    Replies: 8
    Last Post: 15th May 2007, 13:54
  5. QVariant types support for custom properties
    By Dusdan in forum Qt Tools
    Replies: 9
    Last Post: 11th January 2006, 09:55

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.