Page 2 of 2 FirstFirst 12
Results 21 to 29 of 29

Thread: How to solve GUI freezing problem

  1. #21
    Join Date
    Jan 2013
    Posts
    21
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to solve GUI freezing problem

    Hi, kuzulis
    Thank you for your advice. I have tried QtSerialPort. It is an excellent library. But, I still got a question. That is no matter how much data the device send, the QtSerialPort seems that combine them with 512 bytes before it process them.

    I have changed the data block size with 128 bytes and 16K and printed the bytesAvailable() in the slot of readyRead() signal. I found it show 512 bytes every time. The data transfered to PC were correct. I just wonder whether this is correct.


    Added after 1 1:


    Another question
    2. Use async signal/slot approach
    Do you mean connect the signal/slot with Qt::QueuedConnection?
    I tried that and found that it seemed to block the slot so that the data could not be read out(The recieve buffer were full and could not receive any more).
    Last edited by honestapple; 20th March 2013 at 11:18.

  2. #22
    Join Date
    Jan 2009
    Location
    Russia
    Posts
    309
    Thanks
    2
    Thanked 43 Times in 42 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to solve GUI freezing problem

    That is no matter how much data the device send, the QtSerialPort seems that combine them with 512 bytes before it process them
    When each Rx event that received from driver, then QtSerialPort do try to read from the port 512 bytes,
    regardless of how many bytes are actually located in the receive buffer of driver. You can change this
    value in the code to search for optimal performance, but the main feature is that between the two signals
    readyRead(), really come of ~8-10 bytes, depending on the BaudRate, device driver type and etc.


    I found it show 512 bytes every time. The data transfered to PC were correct. I just wonder whether this is correct.
    Most likely this is a bug. But this bug was previously fixed for Windows, please try update repo.
    Or this bug was reproduced on Linux, MacOSX?


    Added after 4 minutes:


    Do you mean connect the signal/slot with Qt::QueuedConnection?
    Yes, I mean connection by default.

    I tried that and found that it seemed to block the slot so that the data could not be read out(The recieve buffer were full and could not receive any more).
    Please provide here your code with receiving data.
    Last edited by kuzulis; 20th March 2013 at 11:38.

  3. #23
    Join Date
    Jan 2013
    Posts
    21
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to solve GUI freezing problem

    Qt Code:
    1. CSerialPortWidget::CSerialPortWidget( QWidget *parent )
    2. : QWidget( parent )
    3. {
    4. /* Initialize widgets and layout */
    5. ...
    6.  
    7. /* Initialize serial port object */
    8. InitDevice();// Reset and handshake using blocking IO
    9.  
    10. connect( m_spSerialPort, SIGNAL( readyRead() ), this, SLOT( slt_DataReceived() ), Qt::QueuedConnection );
    11. connect( m_pbStartSerialPort, SIGNAL( clicked() ), this, SLOT( slt_pbStartSerialPort_Clicked() ) );
    12. }
    To copy to clipboard, switch view to plain text mode 
    When I clicked the start pushbutton, the application send a command to the device. So, the device began to sample data. There are a buffer with 16384 bytes in the device. When the buffer was full, the device upload them through USB virtual COM port.
    Qt Code:
    1. void CSerialPortWidget::slt_DataReceived()
    2. {
    3. qDebug() << m_spSerialPort->bytesAvailable();
    4. QString retSeq = m_spSerialPort->readAll();
    5. // Indeed the QtPlainTextEdit could not display the content. It just displayed a part and frozen. //When I stop transfer, It would display the rest.
    6. m_pteReceive->appendPlainText(retSeq);
    7. QScrollBar *sbScroll = m_pteReceive->verticalScrollBar();
    8. sbScroll->setValue( sbScroll->maximum() );
    9. }
    To copy to clipboard, switch view to plain text mode 
    If I use the Qt:irectConnection, the output block size by qDebug() is 512 bytes(No matter how much data the device transfered actually). If I use the Qt::QueuedConnection, the output of the qDebug is the following:
    512
    3584
    0
    0
    0
    0
    0
    0
    512
    3584
    0
    0
    0
    0
    0
    0
    512
    3584
    0
    0
    0
    0
    0
    0
    512
    3584
    0
    0
    0
    0
    0
    0
    ...// Same as above
    512
    8192 // I have set the size of receive buffer to 8192 bytes. From now on, It did not change any more
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0

  4. #24
    Join Date
    Jan 2009
    Location
    Russia
    Posts
    309
    Thanks
    2
    Thanked 43 Times in 42 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to solve GUI freezing problem

    1. You use last QtSerialPort repo?
    2. You try on Windows or another OS?
    3. Do not use setReadBufferSize() if there are no reasons.

    UPD: Seems, all rigth, your device send to you packet of data with 4096 bytes each.. What are the problems?
    Last edited by kuzulis; 20th March 2013 at 12:54.

  5. #25
    Join Date
    Jan 2013
    Posts
    21
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to solve GUI freezing problem

    I have downloaded the stable version of sourcecode(Wednesday March 20 2013) from the link "http://qt.gitorious.org/qt/qtserialport".

    The platform: visual studio 2008 + QT4.8.6 on Windows XP

    I have removed the setReadBufferSize().

    Now, If I use the Qt :: DirectConnection, the result is the same as above. If I use the Qt::QueuedConnection, the output of the qDebug is the following:
    512
    3584
    4096
    8192
    8192
    12288
    16384
    16384
    24576
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    16384
    0
    0
    0
    ... Always zeros.

    The data block size is correct. But, It seems that these zeros means that there is readyRead signal but the avalible bytes are zero. It seems contradict. I met this condition before. When I used the waitForReadyRead function(I used this function to receive data in device initialization stage), I must close the port after receive some data successfully. Otherwise, It would got a readyRead signal with zero avaliable byte. If I closed the port and reopen it for next receiving, everything is OK.

  6. #26
    Join Date
    Jan 2009
    Location
    Russia
    Posts
    309
    Thanks
    2
    Thanked 43 Times in 42 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to solve GUI freezing problem

    ... Always zeros.
    Zeros - this is a consequence QueuedConnection.

    The fact that readyRead() signal is emitted each time when successfully added a portion of the data in the internal buffer.
    But because slot is called NOT immediatelly - but in queue, this lead to this behavior.

    For more information:
    ~~~~~~~~~~~~~~~~

    For example, you receive 100 bytes, but really this data stream can received as chunk per chunk by 10 byte each.
    So, then you should get the following behavior:


    Automatically processing from class internally:

    01. RX_EVENT occur -> Read 10 bytes -> emit ReadyRead() ( really bytes available == 10 )
    02. RX_EVENT occur -> Read 10 bytes -> emit ReadyRead() ( really bytes available == 20 )
    ...
    ...
    09. RX_EVENT occur -> Read 10 bytes -> emit ReadyRead() ( really bytes available == 90 )
    10. RX_EVENT occur -> Read 10 bytes -> emit ReadyRead() ( really bytes available == 100 )

    Read slot sequence :

    01. Called Slot: -> port->bytesAvailable() == 10, port->readAll() ( after read, really bytes available == 90)
    ...
    <some long time> // It was some time between calls to the two slots, for example, at this moment Qt event-loop was a bit loaded. So, we can get next port->bytesAvailable() > 10 byte!
    ...
    02. Called Slot: -> port->bytesAvailable() == 90, port->readAll() ( after read, really bytes available == 0)
    03. Called Slot: -> port->bytesAvailable() == 0, port->readAll() ( after read, really bytes available == 0)
    ...
    ...
    09. Called Slot: -> port->bytesAvailable() == 0, port->readAll() ( after read, really bytes available == 0)
    10. Called Slot: -> port->bytesAvailable() == 0, port->readAll() ( after read, really bytes available == 0)
    It's all because of QueuedConnection!

    So, I do not know if this is a bug or a feature... But I will think about how can reduce the amount
    of emit readyRead() in order to relieve the Qt event-loop.

    Thanks for the interesting catch!

  7. The following user says thank you to kuzulis for this useful post:

    honestapple (21st March 2013)

  8. #27
    Join Date
    Jan 2013
    Posts
    21
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to solve GUI freezing problem

    When each Rx event that received from driver, then QtSerialPort do try to read from the port 512 bytes,
    regardless of how many bytes are actually located in the receive buffer of driver. You can change this value in the code to search for optimal performance.
    Hi kuzulis,
    1. How to change the default value of the bytes read from the port by QtSerialPort?
    2. If I transfer a data block which have bytes less than 512, Does QtSerialPort still read 512 bytes or read actual bytes in the buffer?

  9. #28
    Join Date
    Jan 2009
    Location
    Russia
    Posts
    309
    Thanks
    2
    Thanked 43 Times in 42 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to solve GUI freezing problem

    1. How to change the default value of the bytes read from the port by QtSerialPort?
    Need modify source code in "qserialport_p.h" for ReadChunkSize enum.

    But this "optimization" makes sense only if port speed very big (for example 4Mbod), i.e. if really between implicity
    internal read operations comes to the buffer of driver more than 512 bytes.

    2. If I transfer a data block which have bytes less than 512, Does QtSerialPort still read 512 bytes or read actual bytes in the buffer?
    QtSerialPort always trying to read by chunks by 512 bytes!
    But this internal implementation of a class shan't excite by no means you as the user. It shall be hidden from the user.

    PS:
    Most likely your problems with application performance are related to something another, for example to your design of application.
    Therefore all my responses don't make sense, from the practical point of view of the user, i.e. for your problem.

  10. The following user says thank you to kuzulis for this useful post:

    honestapple (4th April 2013)

  11. #29
    Join Date
    Jan 2013
    Posts
    21
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to solve GUI freezing problem

    Hi,
    Thank you for your detailed explaination and patience!I nearly have got the application to run as what I wanted------receiving data and plotting them in real time. If you does not mind, I still want to have a discussion with you about the phenomenon in the experiments.
    The device communicated the PC through USB to USART pattern. The maximum of the data packet is 64 bytes. In the experiments, I found that when I transfered data with amount less than 64 bytes, etc 32 bytes, The readyRead signal would be generated after every chunks holding 32 bytes were received, even if I used queueconnection to connect the signal with its slot. If the size of chunks was increased to 64 bytes, The readyRead signal would be generated every chunks of 512 bytes received. Indeed, when I print the output of bytesAvailable(), the result was following:
    ...
    512
    3584
    0
    0
    0
    0
    0
    0
    512
    3584
    0
    0
    0
    0
    0
    0
    512
    3584
    ...
    When the size of chunks was larger than 64 bytes, the output was similar to above except that ended with 4096(This probably related with the USB CDC driver I used).
    Perhaps the large amount would lead to a long time GUI operation, so it seem to transfer chunks with smaller size(less than 64 bytes).
    In my experiments, in order to let the GUI have time to do some operation, I sent command to MCU to fetch data every 10 ms.

    I am working with QT4.8.6+QWT6.0.2+QtSerialPort(latest) on Windows XP.

Similar Threads

  1. Replies: 1
    Last Post: 20th July 2012, 16:38
  2. Thread freezing
    By porterneon in forum Qt Programming
    Replies: 0
    Last Post: 3rd November 2011, 10:38
  3. vary hard problem to solve
    By FS Lover in forum Newbie
    Replies: 3
    Last Post: 2nd July 2009, 09:26
  4. How to solve this cc1plus: out of memory problem?
    By triperzonak in forum Qt Programming
    Replies: 2
    Last Post: 28th September 2008, 20:20
  5. Replies: 12
    Last Post: 3rd April 2006, 06:11

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.