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. DBus reply data accessed via QString
QtWS25 Last Chance

DBus reply data accessed via QString

Scheduled Pinned Locked Moved Solved General and Desktop
dbusmethodqstringqvariantqlist
22 Posts 3 Posters 11.3k 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.
  • A Offline
    A Offline
    amonR2
    wrote on 18 Jun 2016, 03:45 last edited by
    #13

    The output of qDebug << args.count(); gives me 1. There is something I have changed in my code's environment: previously it was in release mode and I have just thought to put it in Debug one's which gives more info. With this code:

    QString a1 = args.at(1).toString();
    qDebug() << a1;
    

    my app crashes and the IDE gives me this message: ASSERT failure in QList<T>::at: "index out of range", file /usr/include/qt4/QtCore/qlist.h, line 469. But when I use this one:

    QString a1 = args.at(0).toString();
    qDebug() << a1;
    

    my app doesn't crash and qDebug() gives me an empty string.

    M 1 Reply Last reply 20 Jun 2016, 06:38
    0
    • A amonR2
      18 Jun 2016, 03:45

      The output of qDebug << args.count(); gives me 1. There is something I have changed in my code's environment: previously it was in release mode and I have just thought to put it in Debug one's which gives more info. With this code:

      QString a1 = args.at(1).toString();
      qDebug() << a1;
      

      my app crashes and the IDE gives me this message: ASSERT failure in QList<T>::at: "index out of range", file /usr/include/qt4/QtCore/qlist.h, line 469. But when I use this one:

      QString a1 = args.at(0).toString();
      qDebug() << a1;
      

      my app doesn't crash and qDebug() gives me an empty string.

      M Offline
      M Offline
      micland
      wrote on 20 Jun 2016, 06:38 last edited by
      #14

      @amonR2
      Ok, the argument list contains just one argument - that's why you get the "index out of range" error because you try to access the second argument. Please add the line qDebug() << args.at(0).typeName(); to see the type of the first argument. Maybe it's a list where you find all your expected data in...

      A 1 Reply Last reply 21 Jun 2016, 01:58
      0
      • M micland
        20 Jun 2016, 06:38

        @amonR2
        Ok, the argument list contains just one argument - that's why you get the "index out of range" error because you try to access the second argument. Please add the line qDebug() << args.at(0).typeName(); to see the type of the first argument. Maybe it's a list where you find all your expected data in...

        A Offline
        A Offline
        amonR2
        wrote on 21 Jun 2016, 01:58 last edited by
        #15

        The reply from qDebug() << args.at(0).typeName(); gives me: QDBusArgument.

        M 1 Reply Last reply 21 Jun 2016, 12:50
        0
        • A amonR2
          21 Jun 2016, 01:58

          The reply from qDebug() << args.at(0).typeName(); gives me: QDBusArgument.

          M Offline
          M Offline
          micland
          wrote on 21 Jun 2016, 12:50 last edited by
          #16

          @amonR2
          Huh, a nested QDBusArgument? Well check the inner argument if it serves the expected information:
          args.at(0).value<QDBusArgument>().args().
          (You should really try to inspect the reply using the debugger and iterate through the object tree to see what's encapsulated in the arguments. That's a lot easier than poking with qDebug() - perhaps this link will help you getting started? http://doc.qt.io/qtcreator/creator-debug-mode.html)

          1 Reply Last reply
          0
          • A Offline
            A Offline
            amonR2
            wrote on 22 Jun 2016, 03:22 last edited by
            #17

            @micland said:

            Huh, a nested QDBusArgument?

            sorry I don't understand what you mean there but that's all qDebug displays.
            Then when I try to qDebug thisargs.at(0).value<QDBusArgument>().args();, the compiler says: 'class QDBusArgument' has no member named 'args'. So I tried with this: args.at(0).value<QDBusArgument>() and received the following from the compiler: no match for 'operator<<' in 'qDebug()() << QVariant::value() const [with T = QDBusArgument]()' [...] no known conversion for argument 1 from 'QDebug' to 'QDBusArgument&'.
            Finally, by puting a breakpoint (thank you for the link) at QList<QVariant> args = replyClementine.arguments(); in my code and launching the debug-mode, the compiler stops and shows me this through the "Locals and Expressions" window:

            	args                 	<inaccessible>	QList<QVariant>
            	this	 @0x83f87d8	FenetreNNS
            		QWidget		QWidget
            		Deviselabel	0x0	QLabel *
            		MainLabel	 @0x844d210	QLabel
            		Nextm	 @0x8451f28	QPushButton
            		NoTrackLabel	 @0x8454628	QLabel
            		Play	 @0x844f628	QPushButton
            		Previous	 @0x8451088	QPushButton
            		TemoinSousTitre	false	bool
            		Volume	 @0x8453a48	QSlider
            		VolumeLabel	 @0x844d160	QLabel
            		boutonDeviseBaht	 @0x8439978	QPushButton
            		boutonDeviseDenar	 @0x843cce0	QPushButton
            		boutonDeviseDollar	 @0x843f968	QPushButton
            		boutonDeviseEuro	 @0x8440418	QPushButton
            		boutonDeviseLira	 @0x843e608	QPushButton
            		boutonDevisePeso	 @0x8442098	QPushButton
            		boutonDevisePound	 @0x8444e58	QPushButton
            		boutonDeviseRuble	 @0x843b078	QPushButton
            		boutonDeviseRupee	 @0x844a4b0	QPushButton
            		boutonDeviseWon	 @0x844b2e0	QPushButton
            		boutonDeviseYen	 @0x8448a28	QPushButton
            		boutonDeviseYuan	 @0x8449e70	QPushButton
            		iface_Clementine	 @0x845e788	QDBusInterface
            		machine	 @0x8455420	QStateMachine
            		principalefen	 @0xbffff7b4	FenPrincipale
            		replyClementine		QDBusMessage
            			d_ptr	 @0x845d098	QDBusMessagePrivate
            		signMapper	 @0x8454ac0	QSignalMapper
            		signMapper2	 @0x84553e8	QSignalMapper
            		sliderSousTitre	 @0x844d998	QSlider
            		state1	 @0x8451f60	QState
            		state2	 @0x8451f70	QState
            		str1	"Currency"	QString
            		tempo	 @0x84505b0	QTimer
            
            

            Should I show the content of some other windows?

            M 1 Reply Last reply 22 Jun 2016, 07:05
            0
            • A amonR2
              22 Jun 2016, 03:22

              @micland said:

              Huh, a nested QDBusArgument?

              sorry I don't understand what you mean there but that's all qDebug displays.
              Then when I try to qDebug thisargs.at(0).value<QDBusArgument>().args();, the compiler says: 'class QDBusArgument' has no member named 'args'. So I tried with this: args.at(0).value<QDBusArgument>() and received the following from the compiler: no match for 'operator<<' in 'qDebug()() << QVariant::value() const [with T = QDBusArgument]()' [...] no known conversion for argument 1 from 'QDebug' to 'QDBusArgument&'.
              Finally, by puting a breakpoint (thank you for the link) at QList<QVariant> args = replyClementine.arguments(); in my code and launching the debug-mode, the compiler stops and shows me this through the "Locals and Expressions" window:

              	args                 	<inaccessible>	QList<QVariant>
              	this	 @0x83f87d8	FenetreNNS
              		QWidget		QWidget
              		Deviselabel	0x0	QLabel *
              		MainLabel	 @0x844d210	QLabel
              		Nextm	 @0x8451f28	QPushButton
              		NoTrackLabel	 @0x8454628	QLabel
              		Play	 @0x844f628	QPushButton
              		Previous	 @0x8451088	QPushButton
              		TemoinSousTitre	false	bool
              		Volume	 @0x8453a48	QSlider
              		VolumeLabel	 @0x844d160	QLabel
              		boutonDeviseBaht	 @0x8439978	QPushButton
              		boutonDeviseDenar	 @0x843cce0	QPushButton
              		boutonDeviseDollar	 @0x843f968	QPushButton
              		boutonDeviseEuro	 @0x8440418	QPushButton
              		boutonDeviseLira	 @0x843e608	QPushButton
              		boutonDevisePeso	 @0x8442098	QPushButton
              		boutonDevisePound	 @0x8444e58	QPushButton
              		boutonDeviseRuble	 @0x843b078	QPushButton
              		boutonDeviseRupee	 @0x844a4b0	QPushButton
              		boutonDeviseWon	 @0x844b2e0	QPushButton
              		boutonDeviseYen	 @0x8448a28	QPushButton
              		boutonDeviseYuan	 @0x8449e70	QPushButton
              		iface_Clementine	 @0x845e788	QDBusInterface
              		machine	 @0x8455420	QStateMachine
              		principalefen	 @0xbffff7b4	FenPrincipale
              		replyClementine		QDBusMessage
              			d_ptr	 @0x845d098	QDBusMessagePrivate
              		signMapper	 @0x8454ac0	QSignalMapper
              		signMapper2	 @0x84553e8	QSignalMapper
              		sliderSousTitre	 @0x844d998	QSlider
              		state1	 @0x8451f60	QState
              		state2	 @0x8451f70	QState
              		str1	"Currency"	QString
              		tempo	 @0x84505b0	QTimer
              
              

              Should I show the content of some other windows?

              M Offline
              M Offline
              micland
              wrote on 22 Jun 2016, 07:05 last edited by
              #18

              @amonR2 said:

              Huh, a nested QDBusArgument?
              sorry I don't understand what you mean there but that's all qDebug displays.

              Aye, sorry - I was wrong, read your answer too fast and got confused...
              It's hard to find this error without reproducing it. If I find some time at the weekend I'll try to debug it. Can you tell me which software you installed? will say: what's that player your communicating with?

              A 1 Reply Last reply 23 Jun 2016, 02:24
              0
              • M micland
                22 Jun 2016, 07:05

                @amonR2 said:

                Huh, a nested QDBusArgument?
                sorry I don't understand what you mean there but that's all qDebug displays.

                Aye, sorry - I was wrong, read your answer too fast and got confused...
                It's hard to find this error without reproducing it. If I find some time at the weekend I'll try to debug it. Can you tell me which software you installed? will say: what's that player your communicating with?

                A Offline
                A Offline
                amonR2
                wrote on 23 Jun 2016, 02:24 last edited by
                #19

                @micland
                The name of the player is "Clementine" and I am using Qt 4.8 . No worries, thank you a lot for your help anyway. I will keep looking for a solution. If I can't find anything I will use one of the other APIs. Cheers again.

                M 2 Replies Last reply 27 Jun 2016, 07:48
                0
                • A amonR2
                  23 Jun 2016, 02:24

                  @micland
                  The name of the player is "Clementine" and I am using Qt 4.8 . No worries, thank you a lot for your help anyway. I will keep looking for a solution. If I can't find anything I will use one of the other APIs. Cheers again.

                  M Offline
                  M Offline
                  micland
                  wrote on 27 Jun 2016, 07:48 last edited by
                  #20

                  @amonR2
                  I'm a little bit closer, but did non really succeed...
                  First: Qt 4.8 is some days older, I used 5.6 for my experiements. Inspecting the DBus interface using qdbusviewer (from Qt5.6) ended with the error message "Unable to find method GetMetadata on path /Player in interface org.freedesktop.MediaPlayer" (the method is listed but I can't call it) - but the cli client qdbus provided me the expected data. I can't say if that's a bug in Qt or a "conformity problem", but it shows that calling the clementine DBus interface from Qt works not straight forward.

                  I tried to access the interface using a simple Qt program (like the example code you posted) and got the same reply as you did. Inspecting the received QDBusArgument showed that its currentyType() is a MapType (4) which means that the arguments are organized as a key/value list (the same says the MPRIS spec: see "Metadata" is an array of dict entries in the form (string, variant) eg: {sv}., https://xmms2.org/wiki/MPRIS#.22Metadata.22)

                  I think you have to extract the values manually and play arround with beginMap(), beginMapEntry(), endMapEntry(), endMap() of QDBusArgument. (I spent just a little time but did not succeed ...)
                  But I'm interested if that's the right way so if you find a solution please share it here! (If I find some time I will try it again, too...)

                  1 Reply Last reply
                  1
                  • A amonR2
                    23 Jun 2016, 02:24

                    @micland
                    The name of the player is "Clementine" and I am using Qt 4.8 . No worries, thank you a lot for your help anyway. I will keep looking for a solution. If I can't find anything I will use one of the other APIs. Cheers again.

                    M Offline
                    M Offline
                    micland
                    wrote on 28 Jun 2016, 06:49 last edited by
                    #21

                    @amonR2
                    out of curiousity I was looking for a solution (I didn't know before that maps and structs are supported by DBus). And I found a way - using Qt 5.6, but should work with Qt 4.8 as well:

                        // first the same code as you did already
                        QDBusInterface *iface_Clementine = new QDBusInterface("org.mpris.clementine", "/Player", "org.freedesktop.MediaPlayer", QDBusConnection::sessionBus());
                        if(iface_Clementine->isValid()) {
                            QDBusMessage replyClementine = iface_Clementine->call("GetMetadata");
                            qDebug() << replyClementine;
                            // there is just one argument and this argument is a map
                            QList<QVariant> args = replyClementine.arguments();
                            const QDBusArgument &arg = args[0].value<QDBusArgument>();
                            // the map has to be extracted entry by entry which is a tuple of key and value
                            // in this case, the key is a string but the type of the value depends on the key (string, int, ...)
                            arg.beginMap();
                            while (!arg.atEnd()) {
                                QString key;
                                QDBusVariant value;
                                arg.beginMapEntry();
                                arg >> key >> value;
                                arg.endMapEntry();
                                qDebug() << "Key:" << key << "\t\tValue:" << value.variant();
                            }
                            arg.endMap();
                        }
                    

                    You still have to inspect the type of the value (depends on what the entry represents: album or track number, or whatever). And the argument parsing can be wrapped in a stream operator, see http://doc.qt.io/qt-5/qdbusargument.html#beginMap-1

                    Some further helpul information can be found here: http://stackoverflow.com/questions/20206376/how-do-i-extract-the-returned-data-from-qdbusmessage-in-a-qt-dbus-call

                    I have no clue why the qdbusviewer of Qt 5.6 is unable to call the DBus method but the code snippet above is working fine.

                    A 1 Reply Last reply 30 Jun 2016, 22:57
                    1
                    • M micland
                      28 Jun 2016, 06:49

                      @amonR2
                      out of curiousity I was looking for a solution (I didn't know before that maps and structs are supported by DBus). And I found a way - using Qt 5.6, but should work with Qt 4.8 as well:

                          // first the same code as you did already
                          QDBusInterface *iface_Clementine = new QDBusInterface("org.mpris.clementine", "/Player", "org.freedesktop.MediaPlayer", QDBusConnection::sessionBus());
                          if(iface_Clementine->isValid()) {
                              QDBusMessage replyClementine = iface_Clementine->call("GetMetadata");
                              qDebug() << replyClementine;
                              // there is just one argument and this argument is a map
                              QList<QVariant> args = replyClementine.arguments();
                              const QDBusArgument &arg = args[0].value<QDBusArgument>();
                              // the map has to be extracted entry by entry which is a tuple of key and value
                              // in this case, the key is a string but the type of the value depends on the key (string, int, ...)
                              arg.beginMap();
                              while (!arg.atEnd()) {
                                  QString key;
                                  QDBusVariant value;
                                  arg.beginMapEntry();
                                  arg >> key >> value;
                                  arg.endMapEntry();
                                  qDebug() << "Key:" << key << "\t\tValue:" << value.variant();
                              }
                              arg.endMap();
                          }
                      

                      You still have to inspect the type of the value (depends on what the entry represents: album or track number, or whatever). And the argument parsing can be wrapped in a stream operator, see http://doc.qt.io/qt-5/qdbusargument.html#beginMap-1

                      Some further helpul information can be found here: http://stackoverflow.com/questions/20206376/how-do-i-extract-the-returned-data-from-qdbusmessage-in-a-qt-dbus-call

                      I have no clue why the qdbusviewer of Qt 5.6 is unable to call the DBus method but the code snippet above is working fine.

                      A Offline
                      A Offline
                      amonR2
                      wrote on 30 Jun 2016, 22:57 last edited by
                      #22

                      @micland

                      WOOW!!! Thank you sooo much micland!! It works!!!
                      I tried a code similar to yours but some data were missing. Just needed to do a very tiny modification on your code:

                      qDebug() << key << value.variant().toString();
                      

                      or directly

                      qDebug() << value.variant().toString();
                      

                      Except it, it is perfect! Thank you again.
                      @micland said:

                      I have no clue why the qdbusviewer of Qt 5.6 is unable to call the DBus method but the code snippet above is working fine.

                      I hope it is going to change as I intend to use it or the 5.7 version very soon.

                      Cheers again.

                      1 Reply Last reply
                      0

                      22/22

                      30 Jun 2016, 22:57

                      • Login

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