Results 1 to 16 of 16

Thread: QNetworkReply | readyRead() cut by finished()

  1. #1
    Join Date
    Feb 2014
    Posts
    23
    Qt products
    Qt5
    Platforms
    Windows

    Default QNetworkReply | readyRead() cut by finished()

    Hi,

    I coded to download a RSS file :

    The problem is that the QByteArray seems to be truncated because of the code of the connect finished() -> deleteLater()
    If I don't connect, qdebug() seems to have a weird behavior, I'm not sure what to do.

    At term, I would like to be able to read the entire QByteArray (content of RSS) to fill a local file with some of the content, and it will be a thread loop, to netReply, and others, will be reused.

    Here is my code :
    Qt Code:
    1. void Window::requestRSSalaune(){
    2. QString urlRss = "http://rss.lemonde.fr/c/205/f/3050/index.rss";
    3.  
    4. netRequest = QNetworkRequest(QUrl(urlRss));
    5. netReply = netMan->get(netRequest);
    6.  
    7. QObject::connect (netReply, SIGNAL(readyRead()), this, SLOT(downloadedRSSalaune())) ;
    8.  
    9. //QObject::connect (netReply, SIGNAL(finished()), netReply, SLOT(deleteLater())) ;
    10. }
    11.  
    12. void Window::downloadedRSSalaune(){
    13.  
    14. qDebug() << netReply->errorString();
    15.  
    16. if(netReply->error() != QNetworkReply::NoError)
    17. return;
    18.  
    19. QByteArray data =QByteArray(netReply->readAll());
    20.  
    21.  
    22. int statusCode = netReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    23. qDebug() << QVariant(statusCode).toString();
    24.  
    25. if(data.isEmpty())
    26. return;
    27.  
    28. qDebug()<<data;
    29. }
    To copy to clipboard, switch view to plain text mode 

    First, connect finished is commented, here is the result :

    Qt Code:
    1. "Unknown error"
    2. "200"
    3. "<?xml><rss><channel>[..]and lot of other words but during the sen"
    4. "Unknown error"
    5. "200"
    6. "tence, qDebug() printed others things, as if the function was called another time during the print of data</guid></item></channel></rss>"
    To copy to clipboard, switch view to plain text mode 

    Secondly, if I uncomment the connection finished() | deleteLater() :
    Qt Code:
    1. "Unknown error"
    2. "200"
    3. "<?xml version='1.0' encoding='UTF-8'?>[...] and other words until this mome"
    4. "Unknown error"
    5. "200"
    To copy to clipboard, switch view to plain text mode 

    So in this second case, the printing of data is not finished so seemed to be cut.
    In the second case, when I uncomment, I have some execution where the qDebug() print is similar as when it's commented, it's very not regular.


    So I don't really know how to manage it
    Thanks in advance for your contribution.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QNetworkReply | readyRead() cut by finished()

    Quote Originally Posted by AmirH View Post
    So in this second case, the printing of data is not finished so seemed to be cut.
    If you are referring to the "mome" then this has likely been the end of the buffer as received in that slot call.
    As you can see in the first example, the data continues in the next invocation, when the next readRead() signal is handled.

    Cheers,
    _

  3. #3
    Join Date
    Feb 2014
    Posts
    23
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QNetworkReply | readyRead() cut by finished()

    ow, ok,
    so how can I have all the content to analyse, shall I append the content of the reply in a new QFile?

    and should I still use deleteLater() ? it seems to interompt the advancement of the download.

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QNetworkReply | readyRead() cut by finished()

    Quote Originally Posted by AmirH View Post
    so how can I have all the content to analyse
    By reading all content whenever new content becomes available or by reading all content at the end of the operation.

    Quote Originally Posted by AmirH View Post
    shall I append the content of the reply in a new QFile?
    A file is a good option if the amount of data can't fit into memory, etc.

    Quote Originally Posted by AmirH View Post
    and should I still use deleteLater() ?
    If you want to free the resources associated with the network reply object. Most programs do.

    Cheers,
    _

  5. #5
    Join Date
    Feb 2014
    Posts
    23
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QNetworkReply | readyRead() cut by finished()

    Hi,
    I have another problem and I think it's no use to open a new thread.

    here is the code modified the slot:

    Qt Code:
    1. void Window::downloadedRSSalaune(){
    2.  
    3. qDebug() << netReply->errorString();
    4.  
    5. if(netReply->error() != QNetworkReply::NoError)
    6. return;
    7.  
    8.  
    9.  
    10. QString filepath = QCoreApplication::applicationDirPath();
    11. filepath.append("\\alaune.xml");
    12. QFile *file = new QFile();
    13. file->setFileName(filepath);
    14.  
    15. qDebug()<<"hi1";
    16. if(!file->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
    17. return;
    18. }
    19. qDebug()<<"hi2";
    20. file->resize(0);
    21. file->write(netReply->readAll());
    22. qDebug()<<"hi3";
    23. QDomDocument *domfile = new QDomDocument("alaune_xml");
    24. QString errorStr;
    25. int errorLine;
    26. int errorColumn;
    27.  
    28. if(!(domfile->setContent(file, false, &errorStr, &errorLine,
    29. &errorColumn))){
    30. qDebug()<<errorStr;
    31. qDebug()<<errorLine;
    32. qDebug()<<errorColumn;
    33. return;
    34. }
    35. qDebug()<<"hi4";
    36. file->close();
    37.  
    38. netReply->deleteLater();
    39.  
    40. [...]
    41. }
    To copy to clipboard, switch view to plain text mode 

    and the output :
    Qt Code:
    1. "Unknown error"
    2. hi1
    3. hi2
    4. hi3
    5. "unexpected end of file"
    6. 1
    7. 1
    To copy to clipboard, switch view to plain text mode 

    so it return at setContent with the unexptected end of file for a file that, after I close the program, looks like this :

    alaune.xml

    Qt Code:
    1. <?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet type='text/xsl' href='http://rss.lemonde.fr/xsl/fr/rss.xsl'?>
    2.  
    3. <rss xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0"><channel>[A LOT OF THINGS]</channel></rss>
    To copy to clipboard, switch view to plain text mode 

    i'm wondering if there is a unsynchronized method here. Whatever, where can be the problem ?

    thank u for your help in advance

  6. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QNetworkReply | readyRead() cut by finished()

    I don't see where you reset the file's position to the beginning.

    Also why do you write into a file at all?
    Also why do you write into a file location that will almost certainly not be writeable once the application gets properly installed?
    Also be aware that QDomDocument can not deal with partial documents.

    Cheers,
    _

  7. #7
    Join Date
    Feb 2014
    Posts
    23
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QNetworkReply | readyRead() cut by finished()

    ok, I'm using QByteArray and it work very well, I've got articles titles with urls and the items menu work fine.

    I'm using a file called history.xml that I fill every minutes and located here :

    QString filepath = QCoreApplication::applicationDirPath();
    filepath.append("\\history.xml");

    what path should I define so it will be easy to access for my program when installed in program file via an installer?

  8. #8
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: QNetworkReply | readyRead() cut by finished()

    Look at QStandardPaths.

  9. #9
    Join Date
    Feb 2014
    Posts
    23
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QNetworkReply | readyRead() cut by finished()

    I'm not really sure how to use it, is QStandardPaths:ataLocation the normal use.
    In fact, I would like to know the common use of programs for files that are useless for the user to open it, but may not have to be very protected. What path to choose?

  10. #10
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: QNetworkReply | readyRead() cut by finished()

    Did you read the descriptions for each of the QStandardPaths::StandardLocation enums? There's a description for each that should guide you to a decision. That said, if I understand what you want, the following description of QStandardPaths::AppDataLocation seem to be a pretty good fit:

    Returns a directory location where persistent application data can be stored. This is an application-specific directory. To obtain a path to store data to be shared with other applications, use QStandardPaths::GenericDataLocation

  11. #11
    Join Date
    Feb 2014
    Posts
    23
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QNetworkReply | readyRead() cut by finished()

    Thank u for your advice.

    Here's a problem that I cannot find any solution on web :
    Qt Code:
    1. QString appPath;
    2. appPath = QString(QStandardPaths::​writableLocation(QStandardPaths::AppDataLocation));
    3. qDebug()<<appPath;
    To copy to clipboard, switch view to plain text mode 

    returrn :

    stray '\342' in program
    stray '\200' in program
    stray '\213' in program

    I checked all the '(' and '::', rewrite all the method by hand, cannot figure what's happening

  12. #12
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: QNetworkReply | readyRead() cut by finished()

    Have you by chance copied/pasted code from a web page somewhere? I would suggest selecting all of your code and copying to the clipboard, then paste into notepad or some other text editor where you can paste as plain text.

    Once you do that, copy all of the plain text out of the notepad or text editor and paste as plain text into your source files and see if that resolves your problem.

  13. #13
    Join Date
    Feb 2014
    Posts
    23
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QNetworkReply | readyRead() cut by finished()

    ok, thanks it works now, I have the printing of appDataLocation being AppData\Roaming\DirectNewsFrance

    Here is the function to create history.xml (which will be modified a lot) by copying the model of historymodel.xml, which will be located in the program files folder of my app

    Qt Code:
    1. void Window::createHistoryXml()
    2. {
    3. qDebug()<<"hi1";
    4. QString filepath = QString(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
    5. filepath.append("\\history.xml");
    6. QFileInfo checkFile(filepath);
    7. if (checkFile.exists() && checkFile.isFile()) {
    8. return;
    9. }
    10. qDebug()<<"hi2";
    11. AppFiles::historyXML->setFileName(filepath);
    12.  
    13. QString modelpath = QCoreApplication::applicationDirPath();
    14. modelpath.append("\\historymodel.xml");
    15. QFile *modelXml = new QFile();
    16. modelXml->setFileName(modelpath);
    17. qDebug()<<"hi3";
    18. if(!(modelXml->open(QIODevice::ReadOnly))){
    19. return;
    20. }
    21. qDebug()<<"hi4";
    22. // QDomDocument to parse xml file
    23. QDomDocument *domfile = new QDomDocument("history_xml");
    24. if(!(domfile->setContent(modelXml))){
    25. return;
    26. }
    27. modelXml->close();
    28. qDebug()<<"hi5";
    29. QString write_doc = domfile->toString();
    30.  
    31. if(!(AppFiles::historyXML->open(QIODevice::WriteOnly))){
    32. return;
    33. }
    34. qDebug()<<"hi6";
    35. AppFiles::historyXML->resize(0);
    36. QTextStream stream(AppFiles::historyXML);
    37. stream << write_doc;
    38. AppFiles::historyXML->close();
    39. qDebug()<<"hi7";
    40. }
    To copy to clipboard, switch view to plain text mode 

    no files neither folder under AppData Roaming have been created. Is it something I forgot to do?

    I have printed :

    hi1
    hi2
    hi3
    hi4
    hi5
    Last edited by AmirH; 4th June 2015 at 08:14.

  14. #14
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QNetworkReply | readyRead() cut by finished()

    You probably don't have the path yet: QDir::mkpath()

    Also that looks like a rather wasteful approach to copy a file: QFile::copy()

    But at least don't leak objects! Currently you unnecessarily allocate "modelXml" and "domfile" on the heap and forget to delete them. Just allocate on the stack.

    Cheers,
    _

  15. #15
    Join Date
    Feb 2014
    Posts
    23
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QNetworkReply | readyRead() cut by finished()

    ok thanks, I will copy file and mkdir,
    I always forget to delete allocated objects, I'm always figuring it will be delete at the end of function automaticaly. Maybe I should use make_unique<>. But here on the stack is ok.

  16. #16
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: QNetworkReply | readyRead() cut by finished()

    Quote Originally Posted by AmirH View Post
    no files neither folder under AppData Roaming have been created. Is it something I forgot to do?
    Yes, if you read the documentation, it states that the path returned may not exist, so you may have to create the directory.

Similar Threads

  1. Replies: 6
    Last Post: 14th February 2012, 23:17
  2. Not getting readyRead from a QUdpSocket
    By evelBist in forum Newbie
    Replies: 3
    Last Post: 20th July 2010, 19:43
  3. QNetworkReply & delayed readyRead(() signal
    By dmini in forum Qt Programming
    Replies: 1
    Last Post: 6th November 2009, 13:47
  4. readyRead problem
    By fruzzo in forum Qt Programming
    Replies: 11
    Last Post: 2nd September 2009, 19:50
  5. QExtSerialPort with readyRead()
    By tho97 in forum Qt Programming
    Replies: 4
    Last Post: 27th August 2008, 20:18

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.