Gelöst: QDbus und Tupels(Liste)

Alles rund um die Programmierung mit Qt
Antworten
oprocopio
Beiträge: 32
Registriert: 6. Juni 2005 14:43

Gelöst: QDbus und Tupels(Liste)

Beitrag von oprocopio »

Hallo Zusammen,

ich entwickle für mein Openmoko ein GUI damit ich anrufen, sms schreiben usw kann. Die ganze kommunikation geht über DBUS.

Nun habe ich aber ein kleines Problem und komme nicht mehr weiter.

bei folgender Abfrage:

QDBusInterface *GSM_Network = new QDBusInterface("org.freesmartphone.ogsmd","/org/freesmartphone/GSM/Device","org.freesmartphone.GSM.Network", dbus);
QDBusMessage msg = GSM_Network->call("GetStatus");

bekomme ich als Antwort ein array aus String und Variant.
Also

z.b.

"status" "registriert"
"provider" "swisscom"
"signal" "95"

wie kann ich nun diese Liste auseinander nehmen damit ich die einzelne werte auslesen kann? kennst sich jemand diesbezüglich aus?

falls meine erklärung zu knapp ist einfach fragen.

danke und gruss im voraus

orlando
Zuletzt geändert von oprocopio am 30. Oktober 2008 18:19, insgesamt 1-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Du hast doch die Werte schon wie es aussieht, wo ist also das Problem?
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
oprocopio
Beiträge: 32
Registriert: 6. Juni 2005 14:43

Beitrag von oprocopio »

:D

um den dbus abzufragen gib es auch ein python-programm mdbus.

daher habe ich die werte. waren eigentlich nur als beispiel gedacht.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Die Antwort sollte in QDBusMessage::arguments () stehen. Schonmal nachgeschaut was da steht?
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
oprocopio
Beiträge: 32
Registriert: 6. Juni 2005 14:43

Beitrag von oprocopio »

so sieht der code aus:

QDBusInterface *GSM_Network = new QDBusInterface("org.freesmartphone.ogsmd","/org/freesmartphone/GSM/Device","org.freesmartphone.GSM.Network", dbus);
QDBusMessage msg = GSM_Network->call("GetStatus");
QList<QVariant> attrs = msg.arguments();
QListIterator<QVariant> i(attrs);
while(i.hasNext())
qDebug() << i.next().toString(); //Da es ja ein QVariant ist muss ich es zuerst umwandeln, richtig?

Die Ausgabe ist jedoch leer. Es kommt nichts an.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Vielleicht sind es keine Strings die ankommen. Außerdem sollte man überprüfen ob QDBusAbstractInterface::call() einen Fehler zurückliefert.
mit dem Tool 'qdbus' kann man auch interfaces anfragen - geht es damit?
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
oprocopio
Beiträge: 32
Registriert: 6. Juni 2005 14:43

Beitrag von oprocopio »

Code: Alles auswählen

mdbus -s org.freesmartphone.ogsmd /org/freesmartphone/GSM/Device org.freesmartphone.GSM.Network.GetStatus

Code: Alles auswählen

/org/freesmartphone/GSM/Device: GetStatus ->  dbus.Dictionary({dbus.String(u'registration'): dbus.String(u'home', variant_level=1), dbus.String(u'strength'): dbus.Int32(77, variant_level=1), dbus.String(u'mode'): dbus.String(u'automatic', variant_level=1), dbus.String(u'provider'): dbus.String(u'Swisscom', variant_level=1)}, signature=dbus.Signature('sv'))
mdbus ist praktisch das gleiche wie qdbus.

ich benutze QDBusInterface und nicht QDBusAbstractInterface, ist das ein problem?
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

was liefert denn:

Code: Alles auswählen

 QDBusMessage msg = GSM_Network->call("GetStatus"); 
 qDebug() << msg.type();
 qDebug() << msg.errorMessage();
 qDebug() << msg.errorName();
 qDebug() << msg.arguments();
?
oprocopio
Beiträge: 32
Registriert: 6. Juni 2005 14:43

Beitrag von oprocopio »

hier die Antwort:

2
""
""
(QVariant(QDBusArgument, ) )
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

da haben wir den Salat.. ich habe keine Erfahrung mit DBus, aber ich lese mal daraus, dass
1. Die Liste nur ein Resultat hat (ein QDBusArgument in Form eines QVariants)
2. Dieses QDBusArgument einen neuen Datentyp (z.B. ein "struct") representiert und man diesen kennen sollte/muss

Also da muss man sowas wie

Code: Alles auswählen

  // erstes Element in der Antwort nach "QDBusArgument" casten
  QDBusArgument arg = qvariant_cast<QDBusArgument>(msg.arguments()[0]); 

  // Struct parsen.. Beispiel von http://doc.trolltech.com/4.3/qdbusargument.html#details
  MyStructure mystruct
  arg.beginStructure();
  arg>> mystruct.count >> mystruct.name;
  arg.endStructure();
aber evt. liege ich auch total falsch...
oprocopio
Beiträge: 32
Registriert: 6. Juni 2005 14:43

Beitrag von oprocopio »

sowas habe ich bereits erstellt:

mokophone.h

Code: Alles auswählen

struct GSMStatusAttr {
  QString name;
  QString value;
};

mokophone.cpp

Code: Alles auswählen

Q_DECLARE_METATYPE(GSMStatusAttr)
Q_DECLARE_METATYPE(QList<GSMStatusAttr>)
/* DBus arguments need to handle the << and >> operators */
const QDBusArgument & operator<<(QDBusArgument &arg, const GSMStatusAttr &attrs)
{
        arg.beginStructure();
        arg << attrs.name << attrs.value;
        arg.endStructure();
        return arg;
}

const QDBusArgument & operator>>(const QDBusArgument &arg, GSMStatusAttr &attrs)
{
        arg.beginStructure();
        arg >> attrs.name >> attrs.value;
        arg.endStructure();
        return arg;
}

Code: Alles auswählen

        QDBusArgument arg = qvariant_cast<QDBusArgument>(msg.arguments()[0]);

        GSMStatusAttr mystruct;
        arg.beginStructure();
        arg>> mystruct.name >> mystruct.value;
        arg.endStructure();

        qDebug() << "Name: " << mystruct.name;
        qDebug() << "Value: " << mystruct.value;
Und hier die Ausgaben:

QDBusArgument: write from a read-only object
process 26985: type array 97 not a basic type
process 26985: type invalid 0 not a basic type
QDBusArgument: write from a read-only object
Name: ""
Value: ""
oprocopio
Beiträge: 32
Registriert: 6. Juni 2005 14:43

Gelöst: QDbus und Tupels(Liste)

Beitrag von oprocopio »

Hurra Hurra es hat nun geklappt!!!

und hier die lösung:

mokophone.h
struct GSMStatusAttr {
QString name;
QVariant value;
};


mokophone.cpp

Code: Alles auswählen

Q_DECLARE_METATYPE(GSMStatusAttr) 
Q_DECLARE_METATYPE(QList<GSMStatusAttr>)
/* DBus arguments need to handle the << and >> operators */ 
const QDBusArgument & operator<<(QDBusArgument &arg, const GSMStatusAttr &attrs) 
{ 
	arg.beginStructure();
	arg << attrs.name << (attrs.value).toString(); 
	arg.endStructure(); 
	return arg; 
} 
            
const QDBusArgument & operator>>(const QDBusArgument &arg, GSMStatusAttr &attrs) 
{ 
	arg.beginStructure(); 
	arg >> attrs.name >> attrs.value; 
	arg.endStructure(); 
	return arg; 
} 

Code: Alles auswählen

QDBusMessage msg = GSM_Network->call("GetStatus");
QDBusArgument arg = qvariant_cast<QDBusArgument>(msg.arguments()[0]); 
QList<GSMStatusAttr> list; 
GSMStatusAttr mystruct;
arg.beginStructure();
arg >> list;
arg.endStructure(); 
qDebug() << "Value: " << list[0].name << list[0].value;
Vielen Danken allen die geholfen haben!

gruss

orlando
Antworten