[SailfishDevel] QThread priority

Krisztian Olah fasza2mobile at gmail.com
Wed May 28 17:07:42 UTC 2014


it just calls:

//pointer also a member
parser->addData()
parser->parse()

although it is a bit messy, here is my parser class and its methods:

//header:

#include <QObject>

#include <QXmlStreamReader>

#include <QSharedPointer>

#include "disruption.h"

#include "street.h"

#include "trafficcontainer.h"



class TrafficXmlReader : public QObject

{

    Q_OBJECT

public:

    TrafficXmlReader(QObject* parent = 0);

private:

    //TrafficContainer has a QList<Disruption> and a QHash<int,Street> member

    // and it interacts with 2 corresponding models for each contained container

    QSharedPointer<TrafficContainer> container;

    int count;

    int currentID;

    Disruption currentDisruption;//just a struct containing the strings

    Street currentStreet;//just a struct containing the strings

    bool inDisruption;

    bool inPoint;

    bool inStreet;

    QXmlStreamReader reader;

public:

    void setContainer(QSharedPointer<TrafficContainer>);

    void setDevice(QIODevice*);

signals:

    void finished();

    void partFinished();

public slots:

    void addData(const QByteArray&);

    void parse();

};


#endif // TRAFFICXMLREADER_H



//implementation:

#include "trafficxmlreader.h"

#include <QDebug>

#include <QRegExp>

#include "trafficcontainer.h"


TrafficXmlReader::TrafficXmlReader(QObject* c) :
container(static_cast<TrafficContainer*>(c)),

                                                          count(0),

                                                          currentID(0),

                                                          inDisruption(false),

                                                          inPoint(false),

                                                          inStreet(false)

{

    reader.setNamespaceProcessing(false);

}


void TrafficXmlReader::setContainer(QSharedPointer<TrafficContainer>
newContainer) {

    container.clear();

    container = newContainer;

}

void TrafficXmlReader::setDevice(QIODevice* device) {
reader.setDevice(device); }


//public slots:

void TrafficXmlReader::addData(const QByteArray& data) { reader.addData(data); }

void TrafficXmlReader::parse() {

    while (!reader.atEnd()) {

        reader.readNext();

        ++count;

        if (reader.qualifiedName() == "Disruption") {

            if (reader.isStartElement()) {

                inDisruption = true;

                currentID = reader.attributes().value("id").toInt();

            }

            else if (reader.isEndElement()) {

                currentDisruption.id = currentID;

                currentID = 0;

                container.data()->addDisruption(currentDisruption);

                inDisruption = false;

            }

        }

        else if (inDisruption && reader.qualifiedName() == "status") {

            currentDisruption.status = reader.readElementText();

        }

        else if (inDisruption && reader.qualifiedName() == "severity") {

            currentDisruption.severity = reader.readElementText();

        }

        else if (inDisruption && reader.qualifiedName() == "levelOfInterest") {

            currentDisruption.levelOfInterest = reader.readElementText();

        }

        else if (inDisruption && reader.qualifiedName() == "category") {

            currentDisruption.category = reader.readElementText();

        }

        else if (inDisruption && reader.qualifiedName() == "subCategory") {

            currentDisruption.subCategory = reader.readElementText();

        }

        else if (inDisruption && reader.qualifiedName() == "startTime") {

            currentDisruption.startTime = reader.readElementText();

        }

        //replace ',' with ", " if not followed by a whitespace,
happends many times due to lousy typing

        //it is to make WordWrap possible in gui

        else if (inDisruption && reader.qualifiedName() == "location") {

            QString location = reader.readElementText();

            int i;

            while ((i = location.indexOf(QRegExp(",[^\\s-]"))) != -1 ) {

                location = location.insert(++i, " ");

            }

            currentDisruption.location = location;

        }

        else if (inDisruption && reader.qualifiedName() == "comments") {

            currentDisruption.comments = reader.readElementText();

        }

        else if (inDisruption && reader.qualifiedName() == "currentUpdate") {

            currentDisruption.currentUpdate = reader.readElementText();

        }

        else if (inDisruption && reader.qualifiedName() == "remarkTime") {

            currentDisruption.remarkTime = reader.readElementText();

        }

        else if (inDisruption && reader.qualifiedName() == "lastModTime") {

            currentDisruption.lastModTime = reader.readElementText();

        }

        else if (inDisruption && reader.qualifiedName() == "Point") {

            inPoint = true;

        }

        else if (inDisruption && inPoint && reader.qualifiedName() ==
"coordinatesLL") {

            currentDisruption.coordinates = reader.readElementText();

        }

        //Streets

        else if (inDisruption && reader.qualifiedName() == "Street") {

            if (reader.isStartElement()) {

                inStreet = true;

            }

            else if (reader.isEndElement()) {

                container.data()->addStreet(currentID, currentStreet);

            }

        }

        else if (inDisruption && inStreet && reader.qualifiedName() == "name") {

            QString name = reader.readElementText();

            int i;

            while ((i = name.indexOf(QRegExp(",[^\\s-]"))) != -1 ) {

                name = name.insert(++i, " ");

            }

            currentStreet.name = name;

        }

        else if (inDisruption && inStreet && reader.qualifiedName() ==
"closure") {

            QString closure = reader.readElementText();

                currentStreet.closure = (closure == "Open") ?
"Affected" : closure;

        }

        else if (inDisruption && inStreet && reader.qualifiedName() ==
"directions") {

            currentStreet.directions = reader.readElementText().toLower();

        }


        if (reader.hasError()) {

            if (reader.error() ==
QXmlStreamReader::PrematureEndOfDocumentError) {

                qDebug() << "partFinished";

                emit partFinished();

            }

            else { qDebug() << "An Error has occured while parsing."; }

        }

    }

    if (!reader.hasError()) {

        qDebug() << "parser.atEnd()";

        qDebug() << "Found " << count << " tags";

        emit finished();

    }

}






On 28 May 2014 16:07, Andrey Kozhevnikov <coderusinbox at gmail.com> wrote:

>  need to look into your parseReadyData
>
> 28.05.2014 22:03, Krisztian Olah пишет:
>
> Hi Andrey,
>    Thanks for the answer, your snippet looks very similar to what I have.
> Perhaps if I posted my code segment would be of help in helping me figuring
> out where I'm wrong.
>    During parsing CPU usage reaches 97-100% which causes my GUI to hang(I
> have about 500 000 opening and closing tags and half of the enclosed items
> I need to process: save, in some cases insert spaces, etc), especially
> awkward when I start parsing whilst still fetching the data from
> network(sometimes hangs during pageStack.push() ), but it's bad for up to
> 2-5 seconds nevertheless. I wouldn't mind if parsing took 10 seconds if GUI
> was responsive. This is what I'm doing:
>
>  void SomeClass::someMethod() {
>               MyContainer* container = new MyContainer();
>               //reader has a handle to container, through which it
> populates the container
>               MyXmlStreamReader* parser = new MyXmlStreamReader(container);
>               QThread* parserThread = new QThread();
>               parser->moveToThread(parserThread);
>
>         connect(parser, SIGNAL(finished()), this, SLOT(onParsingFinished) );
>
>         connect(parser, SIGNAL(finished()), parserThread, SLOT(quit()) );
>
>         connect(parser, SIGNAL(finished()), parser, SLOT(deleteLater()) );
>
>         connect(parserThread, SIGNAL(finished()), parserThread, SLOT(deleteLater()) );
>
>          parserThread->start();
>
>          reply = networkMngr->get(QNetworkRequest(someUrl)); //both pointers are class members
>
>          connect(reply, SIGNAL(finished()), this, SLOT(onAllDataRecieved()) );
>
>          //this starts the parser with the data available at the time,
>
>               // when parser reaches the end of xml document it emits its finished() signal
>
>         connect(reply, SIGNAL(readyRead()), this, SLOT(parseReadyData()) );
>
> }
>
>  Thanks again
>
> Kris
>
>
>
> On 28 May 2014 06:16, Andrey Kozhevnikov <coderusinbox at gmail.com> wrote:
>
>>  it can't "doesn't help much". you initializing thread wrong.
>>
>> simple threading way is:
>>
>> MyXmlParser *parser = new MyXmlParser(xmlDocument);
>> QThread *thread = new QThread(parser);
>> parser->moveToThread(thread);
>> QObject::connect(thread, SIGNAL(started()), parser, SLOT(parse()));
>> QObject::connect(parser, SIGNAL(parseComplete(QVariantMap)), this,
>> SLOT(onParseComplete(QVariantMap)));
>> thread->start();
>>
>> 28.05.2014 03:24, Krisztian Olah пишет:
>>
>>        Hi list,
>>   I have a rather large xml file to parse and it causes the UI to freeze,
>> I assingned the parser to a different thread, but it doesn't help much.
>> According to the Qt documentation QThread::setPriority() doesn't work on
>> Linux, is there some kind of workaround that could be used?
>>
>>  Thanks
>> Kris
>>
>>
>>  _______________________________________________
>> SailfishOS.org Devel mailing list
>> To unsubscribe, please send a mail to devel-unsubscribe at lists.sailfishos.org
>>
>>
>>
>> _______________________________________________
>> SailfishOS.org Devel mailing list
>> To unsubscribe, please send a mail to
>> devel-unsubscribe at lists.sailfishos.org
>>
>
>
>
> _______________________________________________
> SailfishOS.org Devel mailing list
> To unsubscribe, please send a mail to devel-unsubscribe at lists.sailfishos.org
>
>
>
> _______________________________________________
> SailfishOS.org Devel mailing list
> To unsubscribe, please send a mail to
> devel-unsubscribe at lists.sailfishos.org
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.sailfishos.org/pipermail/devel/attachments/20140528/db89c885/attachment-0001.html>


More information about the Devel mailing list