[Qt-interest] qscxml and Qhttp

Daniele Giunchi d.giunchi at scsolutions.it
Sat Oct 23 08:47:09 CEST 2010


Great! :)
thank you very much, I apply the changes and now the request works :)
There are a couple of issues I don't understand.

- using the debugger, I notice that it calls two times the
requestFinished, while I was expecting only one.

-  anyway putting in the scxml another state (identical to the initial
one) just after the first myState (here: http://pastebin.ca/1970599)
I want to go on the second state only when the http request has
returned and not only when it is launched.
Is there a method in xml to have this behaviour?

best regards,
daniele

On Fri, Oct 22, 2010 at 9:51 PM,  <noam.rosenthal at nokia.com> wrote:
> Hi Daniele
> This problem has nothing to do with networking, but rather with the scxml file itself.
>
> There's a bug with the <initial> tag, and that can be easily worked around by using:
>  <state id="Main" initial="myState">
>
> But the real bug with the code you posted is:
>      <onexit>
>        <transition target="final"/>
>      </onexit>
>
> you can't put a transition inside onexit... this line means that the transition always occurs, which means the state machine exits myState immediately, removing the bindings etc.
> See http://pastebin.ca/1970290 for a patched version that worked for me (btw using pastebin.ca for code samples is highly reccomeneded :)).
>
> Good luck
> No'am
> ________________________________________
> From: dannox at gmail.com [dannox at gmail.com] On Behalf Of ext Daniele Giunchi [d.giunchi at scsolutions.it]
> Sent: Friday, October 22, 2010 5:18 PM
> To: Rosenthal Noam (Nokia-MS-Qt/RedwoodCity)
> Cc: qt-interest at trolltech.com
> Subject: Re: [Qt-interest] qscxml and Qhttp
>
> Thank you for the reply,
> I create a minimal project in which the proble can be replicated.
>
> I post here the code, divided by main , classes and the scxml file. I
> forgot to told that I use snow leopard and compiled all on 64 bit.
>
> main.cpp--------------------------
> #include <QtCore/QCoreApplication>
> #include "myStateMachine.h"
>
> int main(int argc, char *argv[]) {
>
>    if(argc != 2) {
>        exit(0);
>    }
>    QString workflow(argv[1]);
>
>    QCoreApplication a(argc, argv);
>
>    QScxml *scxml = QScxml::load(workflow);
>    QObject::connect (scxml, SIGNAL(finished()), &a, SLOT(quit()));
>
>    myStateMachine sm(scxml);
>    scxml->registerObject(sm.model(), "");
>    scxml->registerObject(&sm, "");
>
>    scxml->start(); // if used from scripted state machine http doesn't work
>    //sm.executeService(); // if you uncomment this , http request
> works, infact it is emitted the signal.
>
>    return a.exec();
> }
>
> myStateMachine.h ----------------
> #ifndef MYSTATEMACHINE_H
> #define MYSTATEMACHINE_H
>
> #include <QObject>
> #include <qscxml.h>
> #include <myModel.h>
>
> class myStateMachine : public QObject  {
>    Q_OBJECT
>
> public:
>    /// Object constructor.
>    myStateMachine(QScxml *state_machine);
>
>    /// Object destructor.
>    /* virtual */ ~myStateMachine();
>
>    /// Assign the model class to the state machine logic.
>    void setModel(myModel *m);
>
>    /// Return the current model associated with the state machine logic.
>    myModel *model() {return m_Model;}
>
>
> public slots:
>    /// Slot that use the data written inside the model.
>    void executeService();
>
>    //slot for return if is succeded
>    void requestFinished(int,bool);
>
> private:
>    QScxml *m_StateMachine; ///< Reference to the scripting state machine.
>    myModel *m_Model; ///< Reference to the current model.
>
>    unsigned int m_ClientConnectionPort; ///< Port needed to connect
> client to a remote server.
>    QString m_Address; /// Address related to the remote server to connect with.
>
> };
> #endif // MYSTATEMACHINE_H
>
> myStateMachine.cpp ----------------------------
> #include "myStateMachine.h"
>
> #include <QHttpRequestHeader>
> #include <QHttp>
> /*#include <QNetworkAccessManager>
> #include <QNetworkRequest>*/
>
> myStateMachine::myStateMachine(QScxml *state_machine) :
> m_StateMachine(state_machine), m_Model(new myModel()),
> m_ClientConnectionPort(0), m_Address("") {
>    setObjectName("stateMachineLogic");
>    m_Model->setObjectName("model");
> }
>
> myStateMachine::~myStateMachine() {
>    delete m_Model;
> }
>
> void myStateMachine::setModel(myModel *m) {
>    m_Model = m;
> }
>
> void myStateMachine::executeService() {
>    //QHttp
>     QHttpRequestHeader header("GET", QUrl::toPercentEncoding("/index.html"));
>     header.setValue("Host", "qt.nokia.com");
>     QHttp *http = new QHttp();
>
>     connect( http, SIGNAL(requestFinished(int,bool)),
> SLOT(requestFinished(int,bool)) );
>
>     http->setHost("qt.nokia.com");
>     http->request(header);
>
>    //Network manager
>    /*QNetworkAccessManager *manager = new QNetworkAccessManager(this);
>    connect(manager, SIGNAL(finished(QNetworkReply*)),
>            this, SLOT(replyFinished(QNetworkReply*)));
>
>    manager->get(QNetworkRequest(QUrl("http://qt.nokia.com")));*/
> }
>
> void myStateMachine::requestFinished(int,bool) {
>    qDebug("Succeded!!");
> }
>
> myModel.h --------------------------
> #ifndef MYMODEL_H
> #define MYMODEL_H
>
> #include <QObject>
>
> class myModel : public QObject {
>    Q_OBJECT
>    Q_PROPERTY(QString ip READ serviceIP WRITE setServiceIP)
>    Q_PROPERTY(QString port READ servicePort WRITE setServicePort)
>    Q_PROPERTY(QString protocol READ serviceProtocol WRITE setServiceProtocol)
>
>
> public:
>    /// Object constructor.
>    myModel();
>
>    /// Set the IP associated with the service to call.
>    void setServiceIP(QString ip);
>
>    /// Set the Port associated with the service to call.
>    void setServicePort(QString port);
>
>    /// Set the Protocol associated with the service to call.
>    void setServiceProtocol(QString protocol);
>
>    /// Return the IP associated with the service.
>    QString serviceIP();
>
>    /// Return the Port associated with the service.
>    QString servicePort();
>
>    /// Return the Protocol associated with the service.
>    QString serviceProtocol();
>
>
>
> private:
>    QString m_Ip; ///< IP associated to the service
>    QString m_Port; ///< Port associated to the service
>    QString m_Protocol; ///< Protocol associated to the service
>
> };
>
> inline QString myModel::serviceIP() {
>    return m_Ip;
> }
>
> inline QString myModel::servicePort() {
>    return m_Port;
> }
>
> inline QString myModel::serviceProtocol() {
>    return m_Protocol;
> }
>
> #endif // MYMODEL_H
>
>
> myModel.cpp -------------------------
>
> #include "myModel.h"
>
> myModel::myModel() {
> }
>
> void myModel::setServiceIP(QString ip) {
> //    mafMsgDebug() << "ip: " << ip;
>    m_Ip = ip;
> }
>
> void myModel::setServicePort(QString port) {
> //    mafMsgDebug() << "port: " << port;
>    m_Port = port;
> }
>
> void myModel::setServiceProtocol(QString protocol) {
> //    mafMsgDebug() << "protocol: " << protocol;
>    m_Protocol = protocol;
> }
>
>
> workflow.scxml-------------------
> <?xml version="1.0" encoding="UTF8"?>
> <!-- A wrapper state that contains all other states in this file
> - it represents the complete state machine --> <scxml
> xmlns="http://www.w3.org/2005/07/scxml"
>       version="1.0"
>       initial="Main">
>  <state id="Main">
>    <!-- its initial state is SibaState -->
>    <initial>
>      <transition target="myState"/>
>    </initial>
>
>    <!-- SibaState -->
>    <state id="myState">
>      <invoke type="q-bindings">
>        <content>
>          [[model, "ip", "127.0.0.1"],
>           [model, "port", "80"],
>           [model, "protocol", "Http"]]
>            </content>
>          </invoke>
>
>      <!-- entered in SibaState -->
>      <onentry>
>        <script>stateMachineLogic.executeService();</script>
>      </onentry>
>
>      <onexit>
>        <transition target="final"/>
>      </onexit>
>    </state>
>
>  </state>
>  <final id="final"/>
> </scxml>
>
>
> If executeService is called without scripted state machine, directly
> from main, requestFinished SLOT is called, while using the
> sm no :(
>
> best regards,
> Daniele
>
>
> On Thu, Oct 21, 2010 at 2:39 PM,  <noam.rosenthal at nokia.com> wrote:
>> Hi Daniele
>> Sounds like a problem but it also sounds fixable ~
>> If you post some actual code that shows the problem it would help me help you :)
>>
>> No'am
>> ________________________________________
>> From: qt-interest-bounces at trolltech.com [qt-interest-bounces at trolltech.com] On Behalf Of ext Daniele Giunchi [d.giunchi at scsolutions.it]
>> Sent: Thursday, October 21, 2010 1:27 PM
>> To: qt-interest at trolltech.com
>> Subject: [Qt-interest] qscxml and Qhttp
>>
>> Dear All,
>> I've a problem. I've implemented a QStateMachine using qscxml,
>> creating my scxml file and loading it.
>> It seems to work without any problem except for this: in a function
>> that is successfully called from the script
>> there is a sectiob code which use QHttp, and its request doesn't work.
>> I connect the "requestFinished" signal of QHttp with my slot but
>> nothing. If I try to run this code without using QScxml but
>> writing in C++ the state machine code,  with the same function, the
>> same connect... it works :^/ but obviously I need absolutely to script
>> this workflow.
>>
>> Can anyone help me please?
>> thank you very much,
>>
>> daniele
>>
>> p.s. I try also using QNetworkAccessManager but there is no difference.
>> _______________________________________________
>> Qt-interest mailing list
>> Qt-interest at trolltech.com
>> http://lists.trolltech.com/mailman/listinfo/qt-interest
>>
>




More information about the Qt-interest-old mailing list