Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QDebug with custom typed QVariant
Forum Updated to NodeBB v4.3 + New Features

QDebug with custom typed QVariant

Scheduled Pinned Locked Moved Solved General and Desktop
qt 4.8.1qt 5.6.0qvariantcustom typeqdebug
10 Posts 4 Posters 6.2k Views 4 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • E Offline
    E Offline
    enmaniac
    wrote on 27 Jan 2017, 17:54 last edited by enmaniac
    #1

    Hi all,

    I am having a custom type which I use with QVariant. Everything works fine here.
    One thing I seem not be able to do though is to properly serialize it to debug output.
    For instance:

      QColor colr;
      QVariant colorv = QVariant::fromValue(colr);
    
      qDebug() << colorv;
    

    generates such output:

    QVariant(QColor, QColor(Invalid))

    My type generates such:

    QVariant(Point3F, )

    My type is registered with Q_DECLARE_METATYPE and has its own << operator defined which is never called:

    Q_DECLARE_METATYPE(Point3F);
    QDebug operator << (QDebug, const Point3F&);
    

    Anyone knows how I can ensure stream operator is called if I stream the variant containing my type ?

    Cheers!

    Cheers!

    K 1 Reply Last reply 27 Jan 2017, 18:53
    0
    • E enmaniac
      27 Jan 2017, 17:54

      Hi all,

      I am having a custom type which I use with QVariant. Everything works fine here.
      One thing I seem not be able to do though is to properly serialize it to debug output.
      For instance:

        QColor colr;
        QVariant colorv = QVariant::fromValue(colr);
      
        qDebug() << colorv;
      

      generates such output:

      QVariant(QColor, QColor(Invalid))

      My type generates such:

      QVariant(Point3F, )

      My type is registered with Q_DECLARE_METATYPE and has its own << operator defined which is never called:

      Q_DECLARE_METATYPE(Point3F);
      QDebug operator << (QDebug, const Point3F&);
      

      Anyone knows how I can ensure stream operator is called if I stream the variant containing my type ?

      Cheers!

      K Offline
      K Offline
      koahnig
      wrote on 27 Jan 2017, 18:53 last edited by koahnig
      #2

      @enmaniac

      You need a custom streaming operator for QDebug. Here is an example in the docs for QDebug.

      [edit:koahnig] Sorry, I did not see the part related to QVariant. I guess that would as if converted back to your original object.
      probably like

      qDebug() << colorv.value<QColor>();
      

      Vote the answer(s) that helped you to solve your issue(s)

      1 Reply Last reply
      1
      • E Offline
        E Offline
        enmaniac
        wrote on 27 Jan 2017, 19:01 last edited by
        #3

        Hi @koahnig ,

        You mean that ?

        QDebug operator << (QDebug, const Point3F&);
        

        I already have it but it does not seem to be called.

        Cheers!

        K 1 Reply Last reply 27 Jan 2017, 19:04
        0
        • E enmaniac
          27 Jan 2017, 19:01

          Hi @koahnig ,

          You mean that ?

          QDebug operator << (QDebug, const Point3F&);
          

          I already have it but it does not seem to be called.

          K Offline
          K Offline
          koahnig
          wrote on 27 Jan 2017, 19:04 last edited by
          #4

          @enmaniac
          Sorry, I had not read completely to the end.

          I did not see the part related to QVariant. I guess that would as if converted back to your original object.
          probably like

          qDebug() << colorv.value<QColor>();

          Vote the answer(s) that helped you to solve your issue(s)

          1 Reply Last reply
          0
          • E Offline
            E Offline
            enmaniac
            wrote on 27 Jan 2017, 19:15 last edited by enmaniac
            #5

            Yes, that probably would work but thats what I would like to avoid doing, since I log many different types with the single log function.

            Somehow, for Qt types like QSize and QColor streaming the QVariant into QDebug works just fine. Their streaming operators are called.
            I would like to find out what needs to be done for custom types in order for QVariant to actually call the custom stream handler.

            Probably, there is a way to install my handler for particular custom type but I am not sure.

            Looking into the code I could see the following for QVariant:

            QDebug operator<<(QDebug dbg, const QVariant &v)
            {
                QDebugStateSaver saver(dbg);
                const uint typeId = v.d.type;
                dbg.nospace() << "QVariant(";
                if (typeId != QMetaType::UnknownType) {
                    dbg << QMetaType::typeName(typeId) << ", ";
                    bool userStream = false;
                    bool canConvertToString = false;
                    if (typeId >= QMetaType::User) {
                        userStream = QMetaType::debugStream(dbg, constData(v.d), typeId);
                        canConvertToString = v.canConvert<QString>();
                    }
                    if (!userStream && canConvertToString)
                        dbg << v.toString();
                    else if (!userStream)
                        handlerManager[typeId]->debugStream(dbg, v);
                } else {
                    dbg << "Invalid";
                }
                dbg << ')';
                return dbg;
            }
            

            If I could somehow make my type convertable to QString maybe it would work, though I dont know how to accomplish it.

            Cheers!

            1 Reply Last reply
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 27 Jan 2017, 22:28 last edited by
              #6

              Hi,

              What does your custom debug << operator do ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • E Offline
                E Offline
                enmaniac
                wrote on 28 Jan 2017, 00:16 last edited by
                #7

                Hi!

                Nothing special just logs some data:

                QDebug operator << (QDebug debug, const Point3F& point)
                {
                  QDebugStateSaver saver(debug);
                
                  debug.nospace() << "Point3F(" << point.x() << ", " << point.y() << ", " << point.z() << ")";
                
                  return debug;
                }
                

                Note that if I do stream the object directly it works as expected e.g.:

                qDebug() << Point3F();
                

                Shows:

                Point3F(0, 0, 0)

                It is just when the object is inside of QVariant, the logging is broken.

                Cheers!

                1 Reply Last reply
                0
                • E Offline
                  E Offline
                  enmaniac
                  wrote on 28 Jan 2017, 15:02 last edited by
                  #8

                  I am not sure if it is possible or how to add the file here with a sample project but there is the full example for anyone interested to test:

                  #include <QCoreApplication>
                  #include <QString>
                  #include <QVariant>
                  #include <QDebug>
                  #include <QSize>
                  
                  class MyClass
                  {
                    public:
                  
                      MyClass() {}
                      MyClass(const QString& text) : m_text(text) {}
                      MyClass(const MyClass& other) : m_text(other.text()) {}
                  
                      const QString& text() const { return m_text; }
                  
                    private:
                  
                      QString m_text;
                  };
                  Q_DECLARE_METATYPE(MyClass);
                  QDebug operator << (QDebug debug, const MyClass& object)
                  {
                    debug.nospace() << "MyClass(" << object.text() << ")";
                  
                    return debug;
                  }
                  int main(int argc, char *argv[])
                  {
                    QCoreApplication app(argc, argv);
                  
                    MyClass myClass("This is my text");
                    QVariant vMyClass = QVariant::fromValue(myClass);
                  
                    // Qt type for which everything works just fine
                    qDebug() << QSize();
                    qDebug() << QVariant::fromValue(QSize());
                  
                    qDebug() << myClass;  // This produces: MyClass("This is my text")
                    qDebug() << vMyClass; // This procudes: QVariant(MyClass, )
                                          // while it should: QVariant(MyClass, MyClass("This is my text") )
                  
                    return app.exec();
                  }
                  
                  I have tested on Ubuntu, Qt 4.8.1 and Qt 5.6.0

                  Cheers!

                  K 1 Reply Last reply 28 Jan 2017, 16:05
                  1
                  • E enmaniac
                    28 Jan 2017, 15:02

                    I am not sure if it is possible or how to add the file here with a sample project but there is the full example for anyone interested to test:

                    #include <QCoreApplication>
                    #include <QString>
                    #include <QVariant>
                    #include <QDebug>
                    #include <QSize>
                    
                    class MyClass
                    {
                      public:
                    
                        MyClass() {}
                        MyClass(const QString& text) : m_text(text) {}
                        MyClass(const MyClass& other) : m_text(other.text()) {}
                    
                        const QString& text() const { return m_text; }
                    
                      private:
                    
                        QString m_text;
                    };
                    Q_DECLARE_METATYPE(MyClass);
                    QDebug operator << (QDebug debug, const MyClass& object)
                    {
                      debug.nospace() << "MyClass(" << object.text() << ")";
                    
                      return debug;
                    }
                    int main(int argc, char *argv[])
                    {
                      QCoreApplication app(argc, argv);
                    
                      MyClass myClass("This is my text");
                      QVariant vMyClass = QVariant::fromValue(myClass);
                    
                      // Qt type for which everything works just fine
                      qDebug() << QSize();
                      qDebug() << QVariant::fromValue(QSize());
                    
                      qDebug() << myClass;  // This produces: MyClass("This is my text")
                      qDebug() << vMyClass; // This procudes: QVariant(MyClass, )
                                            // while it should: QVariant(MyClass, MyClass("This is my text") )
                    
                      return app.exec();
                    }
                    
                    I have tested on Ubuntu, Qt 4.8.1 and Qt 5.6.0
                    K Offline
                    K Offline
                    kshegunov
                    Moderators
                    wrote on 28 Jan 2017, 16:05 last edited by kshegunov
                    #9

                    I believe you need to register the debug stream operator.

                    Read and abide by the Qt Code of Conduct

                    E 1 Reply Last reply 28 Jan 2017, 16:49
                    3
                    • K kshegunov
                      28 Jan 2017, 16:05

                      I believe you need to register the debug stream operator.

                      E Offline
                      E Offline
                      enmaniac
                      wrote on 28 Jan 2017, 16:49 last edited by
                      #10

                      @kshegunov Thank you! That was the missing part!!

                      Cheers!

                      1 Reply Last reply
                      0

                      4/10

                      27 Jan 2017, 19:04

                      • Login

                      • Login or register to search.
                      4 out of 10
                      • First post
                        4/10
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved