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
QtWS25 Last Chance

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.1k Views
  • 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

                      10/10

                      28 Jan 2017, 16:49

                      • Login

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