Results 1 to 11 of 11

Thread: Custom type registration on QVariant & toString()

  1. #1

    Default Custom type registration on QVariant & toString()

    I have declared my custom type with Q_DECLARE_METATYPE(MyStruct) and want to call toString() on the corresponding QVariant. But it doesn't work. Is it possible?

    Qt Code:
    1. struct MyStruct {
    2. public:
    3. MyStruct() {}
    4. MyStruct(const MyStruct& struct)
    5. : name( struct.name ) {
    6. }
    7. ~MyStruct() {}
    8. QString toString() const { return name; }
    9.  
    10. QString name;
    11. };
    12.  
    13. Q_DECLARE_METATYPE(MyStruct)
    14.  
    15. int main() {
    16. MyStruct struct;
    17. struct.name = "Test";
    18. QVariant v = QVariant::fromValue(struct);
    19. bool result = v.isValid(); // = true
    20. MyStruct struct2 = v.value<MyStruct>(); // OK
    21. QString output = v.toString(); // fails!!!
    22. return 0;
    23. }
    To copy to clipboard, switch view to plain text mode 

  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: Custom type registration on QVariant & toString()

    No, it's not possible. You need to cast to your type first and then call QString on the resulting variable.
    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

    Default Re: Custom type registration on QVariant & toString()

    Mh, not good. I want it to use in a custom ListModel (e.g. QStringListModel) for a widget and want my model to be reusable.
    Are there any other possiblities implementing an internal QVariant + toString()? I just need a toString-Method for displaying purposes. I thought QVariant would be right solution for this, but obviously I can just use its "container" function. The internal Qt types like QString, qint etc. are overloaded by QVariant toString() implementation.

  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: Custom type registration on QVariant & toString()

    Could you explain with more details what do you mean about the model? Maybe it's enough to implement a custom delegate that is aware of your data structure?
    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
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Custom type registration on QVariant & toString()

    Quote Originally Posted by wysota View Post
    No, it's not possible. You need to cast to your type first and then call QString on the resulting variable.
    Why can't he add a cast operator to his MyStruct class?

    Qt Code:
    1. struct MyStruct
    2. {
    3. // ...
    4. operator const QString & () const { return name; }
    5. }
    To copy to clipboard, switch view to plain text mode 

    Wouldn't that end up getting invoked by QVariant:toString()? He might have to declare his variant as a "String" type, but it should then work if I understand the docs correctly.

  6. #6

    Default Re: Custom type registration on QVariant & toString()

    operator const QString & () const { return name; }
    Doesn't work either.

    My intention was to build a model like QStringListModel and save information how often an item is added. This additional information should not be in the model but in the registered type (MyStruct).
    Pseudocode:
    Qt Code:
    1. class QVariantListModel : QAbstractListModel {
    2. bool setData(...);
    3. QVariantList lst;
    4. };
    5.  
    6. int main() {
    7. MyStruct struct;
    8. struct.name = "Test";
    9. struct.counter += 1;
    10. QVariantListModel model = new QVariantListModel();
    11. model->setData(QModelIndex(), QVariant::fromValue(struct)); // Add data to model.
    12. return 0;
    13. }
    To copy to clipboard, switch view to plain text mode 

    Possible internal list should look like this:
    lst = { ["entry1",2], ["entry2", 5] }
    Last edited by zickedi; 3rd March 2012 at 22:48.

  7. #7
    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: Custom type registration on QVariant & toString()

    Quote Originally Posted by d_stranz View Post
    Why can't he add a cast operator to his MyStruct class?
    Because he wants to convert to QString from QVariant and not his own class.

    Wouldn't that end up getting invoked by QVariant:toString()?
    No. QVariant::toString() calls QVariant::canConvert<QString>() and that returns false for custom types.

    He might have to declare his variant as a "String" type
    This is not possible, each type gets its own meta type id.

    Quote Originally Posted by zickedi View Post
    My intention was to build a model like QStringListModel and save information how often an item is added. This additional information should not be in the model but in the registered type (MyStruct).
    Pseudocode:
    Qt Code:
    1. class QVariantListModel : QAbstractListModel {
    2. bool setData(...);
    3. QVariantList lst;
    4. };
    5.  
    6. int main() {
    7. MyStruct struct;
    8. struct.name = "Test";
    9. struct.counter += 1;
    10. QVariantListModel model = new QVariantListModel();
    11. model->setData(QModelIndex(), QVariant::fromValue(struct)); // Add data to model.
    12. return 0;
    13. }
    To copy to clipboard, switch view to plain text mode 

    Possible internal list should look like this:
    lst = { ["entry1",2], ["entry2", 5] }
    I think you are approaching the problem from the wrong side. I think you want something like this (not tested):

    Qt Code:
    1. class MyModel : public QAbstractTableModel {
    2. public:
    3. MyModel(QObject *parent = 0) : QAbstractListModel(parent) {}
    4. int rowCount(const QModelIndex &parent = QModelIndex()) const { return parent.isValid() ? 0 : m_data.count(); }
    5. int columnCount(const QModelIndex &parent = QModelIndex()) const { return parent.isValid() ? 0 : 2; }
    6. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
    7. if(index.row() < 0 || index.row() >= m_data.count()) return QVariant();
    8. const MyStruct &item = m_data.at(index.row());
    9. const int c = index.column();
    10. switch(role) {
    11. case Qt::DisplayRole:
    12. case Qt::EditRole:
    13. if(c==0) return item.name;
    14. if(c==1) return item.count;
    15.  
    16. break;
    17. }
    18. return QVariant();
    19. }
    20. // follow with insertRows(), removeRows() and setData() implementations to make the model read-write
    21. private:
    22. QList<MyStruct> m_data;
    23. };
    To copy to clipboard, switch view to plain text mode 
    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.


  8. #8
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Custom type registration on QVariant & toString()

    I agree that it does seem like the OP realy should be creating amodel such as your example.

    But in the general case of a custom QVariant type, from the docs:

    QString QVariant::toString () const

    Returns the variant as a QString if the variant has type() String, Bool, ByteArray, Char, Date, DateTime, Double, Int, LongLong, StringList, Time, UInt, or ULongLong; otherwise returns an empty string.
    If QVariant can return a QString for all of these built-in and Qt types, it seem inconsistent that there isn't any way to define that conversion for a custom metatype. Is there some Qt design reason why this is not permitted?

  9. #9
    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: Custom type registration on QVariant & toString()

    The reason is that for types built into Qt one can provide static (as in known at the time Qt is compiled, not as in having a "static" modifier) code that performs the conversion. For custom types, the data is stored internally as a void* pointer treating the data itself as a black box. The type may not even be a class, no methods of the type are exposed to QVariant. The code created for such type has to be very generic to work for different kind of data. There is simply no sane way of providing a type-safe conversion such as this (I'm not counting providing a bunch of template overloads for different types as a sane way), at least I cannot think of any. For most types it wouldn't even make any sense to convert them to a string.
    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.


  10. #10

    Default Re: Custom type registration on QVariant & toString()

    Ok, thanks for the tips. I think I have to implement it this way.
    I always thought of something like a class "QVariantListModel" and that class storing and displaying my custom type (displaying just my attribute name). Now I know why there is only a QStringListModel ;-)

  11. #11
    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: Custom type registration on QVariant & toString()

    No, there is QStandardItemModel if you really need it. QStringListModel stores simple strings and nothing more.
    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.


Similar Threads

  1. QVariant custom type.
    By hickscorp in forum Qt Programming
    Replies: 0
    Last Post: 3rd May 2010, 14:23
  2. Using QVariant with custom data type
    By QAlex in forum Qt Programming
    Replies: 3
    Last Post: 4th December 2009, 12:04
  3. 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
  4. QVariant custom/user type comparison
    By gri in forum Qt Programming
    Replies: 2
    Last Post: 12th August 2008, 14:36
  5. QVariant::toString and custom data types
    By Vladimir in forum Qt Programming
    Replies: 2
    Last Post: 16th January 2007, 15:36

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.