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. [SOLVED]QVariant in signal argument and QSignalSpy
Forum Updated to NodeBB v4.3 + New Features

[SOLVED]QVariant in signal argument and QSignalSpy

Scheduled Pinned Locked Moved General and Desktop
13 Posts 5 Posters 10.9k Views 1 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.
  • I Offline
    I Offline
    ixSci
    wrote on last edited by
    #1

    Hi folks,

    I have the following code:
    @emit sigEntryDataChanged(c_NameField, QVariant::fromValue(m_strName));//m_strName contains "New string"
    ...
    QSignalSpy Spy(&Entry;, SIGNAL(sigEntryDataChanged(QString, QVariant)));
    ...
    QVERIFY(Arguments[0].toString() == EntryData::c_NameField);//It is ok. The verification is passed
    QVERIFY(Arguments[1].toString() == strName);// That verification is not passed because Arguments[1].toString() yields the empty string!
    @

    strName is the correctly set and passed to the signal emission. I have a several part of code which I try to test but all of them fails!
    It seems like some problem with signals and QVariants in signal arguments.

    Could anyone explain what the problem I've encountered?

    1 Reply Last reply
    0
    • Z Offline
      Z Offline
      ZapB
      wrote on last edited by
      #2

      Please post a complete example. From the above it looks as if you setup the signal spy after you have emitted the signal.

      Nokia Certified Qt Specialist
      Interested in hearing about Qt related work

      1 Reply Last reply
      0
      • I Offline
        I Offline
        ixSci
        wrote on last edited by
        #3

        it is excerpt from the project. Signal is emitted after the QSignalSpy Spy(&Entry;, SIGNAL(sigEntryDataChanged(QString, QVariant)));

        And you can see it in the two last line in my scratch: first signal argument is received right while the second(which is QVariant) is broken. Have you ever used signals with QVariant arguments? I don't want to build a complete example to reproduce it because it will take quite a time to do it. So I just hope to find someone who have faced such a behavior already.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          mlong
          wrote on last edited by
          #4

          I've used QVariants with signals quite extensively. I've never had any issues with anything being broken from the Qt side of things.

          Have you double checked that there is actually a valid QVariant being emitted (i.e., QVariant::fromValue(m_strName) is all good)?

          Software Engineer
          My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

          1 Reply Last reply
          0
          • I Offline
            I Offline
            ixSci
            wrote on last edited by
            #5

            m_strName is good. But how can I check if the QVariant::fromValue(m_strName) is good?
            I think that it should be good as long as the argument is good.
            mlong, have you used QSignalSpy with signals which arguments are QVariants?
            It returns QList of QVariants so maybe it wraps QVAriant into QVariant somehow so I need to unwrap it before? I'll double check my code one more time, though.

            1 Reply Last reply
            0
            • M Offline
              M Offline
              mlong
              wrote on last edited by
              #6

              As ZapB suggested, can you post a more complete example?

              Software Engineer
              My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

              1 Reply Last reply
              0
              • C Offline
                C Offline
                ckakman
                wrote on last edited by
                #7

                @QSignalSpy Spy(&Entry;, SIGNAL(sigEntryDataChanged(QString, QVariant)));@

                Does this code compile with the ';' in @&Entry;@

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  mlong
                  wrote on last edited by
                  #8

                  The extra semicolon is a problem with the code formatting on this site. It was discussed "here":http://developer.qt.nokia.com/forums/viewthread/7889.

                  Software Engineer
                  My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                  1 Reply Last reply
                  0
                  • I Offline
                    I Offline
                    ixSci
                    wrote on last edited by
                    #9

                    I've made the test project:
                    test.h
                    @#ifndef TEST_H
                    #define TEST_H

                    #include <QObject>
                    #include <QString>
                    #include <QVariant>

                    class TestClass: public QObject
                    {
                    Q_OBJECT
                    public:
                    void emitSignal()
                    {
                    QString strFirst("First");
                    QString strSecond("Second");
                    emit sigTest(strFirst, QVariant::fromValue(strSecond));
                    }

                    signals:
                    void sigTest(const QString&, const QVariant&);
                    };

                    #endif // TEST_H
                    @

                    main.cpp
                    @#include <QtCore/QCoreApplication>
                    #include <QtTest/QSignalSpy>
                    #include <QtDebug>
                    #include "test.h"

                    int main(int argc, char *argv[])
                    {
                    QCoreApplication a(argc, argv);
                    TestClass Test;
                    QSignalSpy Spy(&Test;, SIGNAL(sigTest(QString, QVariant)));
                    Test.emitSignal();
                    QList<QVariant> Arguments = Spy.takeFirst();
                    qDebug() << "First Argument: " << Arguments[0].toString() << ", Second arg: " << Arguments[1].toString();
                    return a.exec();
                    }
                    @

                    And it prints: First Argument: "First" , Second arg: ""

                    Project: http://www.sendspace.com/file/56i1ey

                    1 Reply Last reply
                    0
                    • Z Offline
                      Z Offline
                      ZapB
                      wrote on last edited by
                      #10

                      OK sorted it. At first I added a simple receiver class like this to test the argument passing between signals and slots:

                      @
                      class Receiver : public QObject
                      {
                      Q_OBJECT
                      public:
                      Receiver( QObject* parent = 0 )
                      : QObject( parent )
                      {}

                      public slots:
                      void testSlot( const QString& str, const QVariant& v )
                      {
                      qDebug() << Q_FUNC_INFO;
                      qDebug() << "arg1 =" << str;
                      qDebug() << "arg2 =" << v.toString();
                      }
                      };
                      @

                      When connected to your Test object it indeed printed out:

                      @
                      void Receiver::testSlot(const QString&, const QVariant&)
                      arg1 = "First"
                      arg2 = "Second"
                      @

                      as expected. This made me think it was a bug in QSignalSpy not being able to handle QVariant argument types correctly.

                      However, digging deeper and debugging into the source code of QSignalSpy I noticed this function getting called when the signal is emitted:

                      @
                      void appendArgs(void **a)
                      {
                      QList<QVariant> list;
                      for (int i = 0; i < args.count(); ++i) {
                      QMetaType::Type type = static_castQMetaType::Type(args.at(i));
                      list << QVariant(type, a[i + 1]);
                      }
                      append(list);
                      }
                      @

                      Notice that each argument is indeed wrapped in a QVariant. So your argument is getting added to the list correctly just that it is now a QString wrapped in a QVariant wrapped in a QVariant.

                      So to adjust your app to properly print out the argument contents I did this:

                      @
                      QList<QVariant> arguments = spy.takeFirst();
                      qDebug() << "First Argument: " << arguments.at( 0 ).toString();
                      QVariant v = arguments.at( 1 ).value<QVariant>();
                      qDebug() << ", Second arg: " << v.toString();
                      @

                      Notice the extra value<QVariant>() call since QVariant does not have a toVariant() function ;-)

                      Hope this explains it.

                      Nokia Certified Qt Specialist
                      Interested in hearing about Qt related work

                      1 Reply Last reply
                      0
                      • I Offline
                        I Offline
                        ixSci
                        wrote on last edited by
                        #11

                        ZapB, great job, thanks! You have confirmed my thoughts about wrapping, but I have not ever thought about value<QVariant>()

                        1 Reply Last reply
                        0
                        • Z Offline
                          Z Offline
                          ZapB
                          wrote on last edited by
                          #12

                          No problem, you're welcome.

                          Nokia Certified Qt Specialist
                          Interested in hearing about Qt related work

                          1 Reply Last reply
                          0
                          • X Offline
                            X Offline
                            xarragon
                            wrote on last edited by
                            #13

                            I also got bitten by this particular nastiness, your post helped me solve it. Many thanks!

                            1 Reply Last reply
                            0

                            • Login

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