Page 1 of 2 12 LastLast
Results 1 to 20 of 29

Thread: How to solve GUI freezing problem

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

    Default Re: How to solve GUI freezing problem

    Hi,
    I am developping a project about data sampling and realtime display like oscilloscope. The data are transfered to PC with virtual com port which has a high trandfer rate. I am using QT4.8.4 + Qextserialport to accomplish serial port communication on WindowsXP. The following is the link of the reference sourcecode.
    http://www.qtcentre.org/threads/2106...ht=#post103325

    In the sourcecode, the author subclass the QThread and reimplement the run function. The code worked well except when receiving data and update display.
    When the application began to receive data continously and tried to update the content of a qtextbrowser through signal and slots, It would got freeze(The GUI has no response to user input).
    When I removed the gui display part(The application did nothing except receiving data), the application worked well(The application respond to the pushbutton click).
    When I replaced the qtextbrowser widget with qplaintextedit widget, the application could respond to user input slowly.
    I think that perhaps the slow gui operation make the gui freeze.

    1. Please give me some advice on how to solve this problem.

    In addition, I know that there is another method for multithread application which use subclass of QObject and moveToThread method. I have no idea that whether this method could help me get out of the trouble(In fact, I did not think that this method would do some help because the current code could run well without gui operation).

    2. I still want to ask a question about the second method. If I want to generate two thread on serial port using this method, one is for reading operation, the other is for writing operation, how to do that?


    Added after 10 minutes:


    In addition, I search on the google and find the article on the blog "Qt and serial ports | fede.tft's Blog" which perhaps have some relation to my problem. But, I could not access this blog. I will be very appreciate if someone could download this article and send it to me or paste on the board.
    Thanks a lot.
    The following is the blog link:
    Qt and serial ports | fede.tft's Blog
    fedetft.wordpress.com/2010/.../qt-and-serial-ports/
    Last edited by honestapple; 13th March 2013 at 08:54.

  2. #2
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to solve GUI freezing problem

    Show us some REAL code : how You receive data and how You update GUI.

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

    Default Re: How to solve GUI freezing problem

    Code removed, see next post

    In the ReceiveThread::run(), the dataReceived signal in ReceiveThread class is emitted which will trigger another dataReceived signal in MySerialPort class.
    In GUI code, I connect the signal to the slot appendPlainText of the QPlainTextEdit widget.
    connect( m_spSerialPort, SIGNAL(dataReceived(const QByteArray &dataReceived)), m_pteReceive, SLOT( appendPlainText(const QByteArray &dataReceived) ), Qt::QueuedConnection );
    This would make gui not frozen, just very slowly to user input(such as click pushbutton).
    If I changed the widget to QTextBrowser, and create a new slot to insert the received data into textbrowser with insertPlainText method, The GUI would got frozen.(Now, I knew that perhaps this is a time-consuming operation)
    Last edited by wysota; 13th March 2013 at 14:35. Reason: Removed code

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to solve GUI freezing problem

    This code is unreadable. Please post it properly as an attachment.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to solve GUI freezing problem

    Method SendThread::run() does not make sense. The only thing he does well is eating CPU time. Method ReceiveThread::run() also.

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

    Default Re: How to solve GUI freezing problem

    Header:MySerialPort.h
    Qt Code:
    1. #ifndef MYSERIALPORT_H
    2. #define MYSERIALPORT_H
    3. #include <QObject>
    4. #include <QQueue>
    5. #include <QMetaType>
    6. #include <QThread>
    7. #include <QMutex>
    8. #include "qextserialport.h"
    9. Q_DECLARE_METATYPE(BaudRateType);
    10. Q_DECLARE_METATYPE(DataBitsType);
    11. Q_DECLARE_METATYPE(ParityType);
    12. Q_DECLARE_METATYPE(StopBitsType);
    13. Q_DECLARE_METATYPE(FlowType);
    14. class SendThread;
    15. class ReceiveThread;
    16. class MySerialPort : public QObject
    17. {
    18. Q_OBJECT
    19. public:
    20. MySerialPort();
    21. MySerialPort(const QString &name, const BaudRateType baudRate, const DataBitsType dataBits,
    22. const ParityType parity, const StopBitsType stopBits, const FlowType flowControl,
    23. ulong seconds = 0, ulong milliseconds = 10);
    24. ~MySerialPort();
    25. bool open();
    26. bool open(const QString &name, const BaudRateType baudRate, const DataBitsType dataBits,
    27. const ParityType parity, const StopBitsType stopBits, const FlowType flowControl,
    28. ulong seconds = 0, ulong milliseconds = 10);
    29. bool isOpen() const;
    30. void close();
    31. // Setter and getter for the basic property of the QextSerialPort
    32. void setPortName(const QString &name);
    33. QString portName() const;
    34. void setBaudRate(const BaudRateType baudRate);
    35. BaudRateType baudRate() const;
    36. void setDataBits(const DataBitsType dataBits);
    37. DataBitsType dataBits() const;
    38. void setParity(const ParityType parity);
    39. ParityType parity() const;
    40. void setStopBits(StopBitsType stopBits);
    41. StopBitsType stopBits() const;
    42. void setFlowControl(const FlowType flowControl);
    43. FlowType flowControl() const;
    44. void setTimeout(const ulong seconds, const ulong milliseconds);
    45. /*
    46.   Send
    47.   */
    48. void enableSending(); // enable the SerialPort to send data (init the thread)
    49. void disableSending(); // disable the SerialPort to send data (terminate the thread)
    50. bool isSendingEnable() const;
    51. void stopSending(); // stop the currently sending data operation (don't terminate the thread)
    52. uchar sendData(const QByteArray &data); // send data to the SerialPort (enqueue data to the sendThread queue)
    53. // return 1 OK
    54. // return 2 port not open
    55. // return 3 sending operation disable
    56. /*
    57.   Receive
    58.   */
    59. void enableReceiving(); // enable the SerialPort to receive data (init the thread)
    60. void disableReceiving(); // disable the SerialPort to receive data (terminate the thread)
    61. bool isReceivingEnable() const;
    62. void stopReceiving(); // stop the currently receiving data operation (don't terminate the thread)
    63. uchar receiveData(); // Start the receiving thread
    64. // return 1 OK
    65. // return 2 port closed
    66. // return 3 receiving operation disable
    67. signals:
    68. void dataReceived(const QByteArray &dataReceived);
    69. private:
    70. void initPrivateVariable();
    71. private:
    72. QextSerialPort port;
    73. SendThread *sendThread;
    74. ReceiveThread *receiveThread;
    75. bool sendingEnable;
    76. bool receivingEnable;
    77. // Variables to restore the previous state to a reopening of the SerialPort
    78. bool closeCalled;
    79. bool saveStateSendingEnable;
    80. bool saveStateReceivingEnable;
    81. bool saveStateReceiveData;
    82. };
    83. class SendThread : public QThread
    84. {
    85. Q_OBJECT
    86. public:
    87. SendThread(QextSerialPort &adrPort);
    88. ~SendThread();
    89. void addDataToSend(const QByteArray &dataToAdd);
    90. void stopSending();
    91. protected:
    92. void run();
    93. private:
    94. QextSerialPort &port;
    95. QQueue<QByteArray> dataToSend;
    96. QMutex mutexSend;
    97. bool stopped;
    98. };
    99. class ReceiveThread : public QThread
    100. {
    101. Q_OBJECT
    102. public:
    103. ReceiveThread(QextSerialPort &adrPort);
    104. ~ReceiveThread();
    105. void stopReceiving();
    106. protected:
    107. void run();
    108. signals:
    109. void dataReceived(const QByteArray &dataReceived);
    110. private :
    111. QextSerialPort &port;
    112. QMutex mutexReceive;
    113. bool stopped;
    114. };
    115. #endif // MYSERIALPORT_H
    To copy to clipboard, switch view to plain text mode 

    source file:MySerialPort.cpp
    Qt Code:
    1. #include "myserialport.h"
    2. /*
    3.   Private Functions
    4.   */
    5. void MySerialPort::initPrivateVariable()
    6. {
    7. // Init private variable
    8. sendThread = NULL;
    9. receiveThread = NULL;
    10. sendingEnable = false;
    11. receivingEnable = false;
    12. closeCalled = false;
    13. saveStateSendingEnable = false;
    14. saveStateReceivingEnable = false;
    15. saveStateReceiveData = false;
    16. }
    17.  
    18. MySerialPort::MySerialPort()
    19. {
    20. initPrivateVariable();
    21. }
    22. MySerialPort::MySerialPort(const QString &name, const BaudRateType baudRate, const DataBitsType dataBits,
    23. const ParityType parity, const StopBitsType stopBits, const FlowType flowControl,
    24. ulong seconds, ulong milliseconds)
    25. {
    26. initPrivateVariable();
    27. setPortName(name);
    28. setBaudRate(baudRate);
    29. setDataBits(dataBits);
    30. setParity(parity);
    31. setStopBits(stopBits);
    32. setFlowControl(flowControl);
    33. setTimeout(seconds, milliseconds);
    34. }
    35.  
    36. MySerialPort::~MySerialPort()
    37. {
    38. if (sendThread)
    39. {
    40. delete sendThread;
    41. sendThread = NULL;
    42. }
    43. if (receiveThread)
    44. {
    45. delete receiveThread;
    46. receiveThread = NULL;
    47. }
    48. if (isOpen())
    49. port.close();
    50. }
    51.  
    52. // Open the SerialPort
    53. bool MySerialPort::open()
    54. {
    55. bool res = port.open(QIODevice::ReadWrite);
    56. // If the port is reopened after an earlier closure restores the previous state
    57. if (closeCalled)
    58. {
    59. if (saveStateSendingEnable)
    60. enableSending();
    61. if (saveStateReceivingEnable)
    62. enableReceiving();
    63. if (saveStateReceiveData)
    64. receiveData();
    65. closeCalled = false;
    66. }
    67. return res;
    68. }
    69. bool MySerialPort::open(const QString &name, const BaudRateType baudRate, const DataBitsType dataBits,
    70. const ParityType parity, const StopBitsType stopBits, const FlowType flowControl,
    71. ulong seconds, ulong milliseconds)
    72. {
    73. setPortName(name);
    74. setBaudRate(baudRate);
    75. setDataBits(dataBits);
    76. setParity(parity);
    77. setStopBits(stopBits);
    78. setFlowControl(flowControl);
    79. setTimeout(seconds, milliseconds);
    80. //return open();
    81. return port.open(QIODevice::ReadWrite);
    82. }
    83. // SerialPort is open?
    84. bool MySerialPort::isOpen() const
    85. {
    86. return port.isOpen();
    87. }
    88. // Close the SerialPort
    89. void MySerialPort::close()
    90. {
    91. closeCalled = true;
    92. // Save the state
    93. saveStateSendingEnable = isSendingEnable();
    94. saveStateReceivingEnable = isReceivingEnable();
    95. // Close the port
    96. disableReceiving();
    97. disableSending();
    98. port.close();
    99. // TODO: should I stop send and receive?
    100. }
    101. // Setter and getter for the basic property of the QextSerialPort
    102. void MySerialPort::setPortName(const QString &name)
    103. {
    104. port.setPortName(name);
    105. }
    106. QString MySerialPort::portName() const
    107. {
    108. return port.portName();
    109. }
    110. void MySerialPort::setBaudRate(const BaudRateType baudRate)
    111. {
    112. port.setBaudRate(baudRate);
    113. }
    114. BaudRateType MySerialPort::baudRate() const
    115. {
    116. return port.baudRate();
    117. }
    118. void MySerialPort::setDataBits(const DataBitsType dataBits)
    119. {
    120. port.setDataBits(dataBits);
    121. }
    122. DataBitsType MySerialPort::dataBits() const
    123. {
    124. return port.dataBits();
    125. }
    126. void MySerialPort::setParity(const ParityType parity)
    127. {
    128. port.setParity(parity);
    129. }
    130. ParityType MySerialPort::parity() const
    131. {
    132. return port.parity();
    133. }
    134. void MySerialPort::setStopBits(StopBitsType stopBits)
    135. {
    136. port.setStopBits(stopBits);
    137. }
    138. StopBitsType MySerialPort::stopBits() const
    139. {
    140. return port.stopBits();
    141. }
    142. void MySerialPort::setFlowControl(const FlowType flowControl)
    143. {
    144. port.setFlowControl(flowControl);
    145. }
    146. FlowType MySerialPort::flowControl() const
    147. {
    148. return port.flowControl();
    149. }
    150. void MySerialPort::setTimeout(const ulong seconds, const ulong milliseconds)
    151. {
    152. port.setTimeout(seconds, milliseconds);
    153. }
    154. /*
    155.   Send
    156.   */
    157. // Enable the SerialPort to send data (init the thread)
    158. void MySerialPort::enableSending()
    159. {
    160. // If the Sending is not already active AND the sendThead is not initialized
    161. if (!sendingEnable && !sendThread)
    162. {
    163. sendThread = new SendThread(port);
    164. sendingEnable = true;
    165. }
    166. }
    167. // Disable the SerialPort to send data (terminate the thread)
    168. void MySerialPort::disableSending()
    169. {
    170. // If the Sending is already active AND there is a sendThread
    171. if (sendingEnable && sendThread)
    172. {
    173. delete sendThread;
    174. sendThread = NULL;
    175. sendingEnable = false;
    176. }
    177. }
    178. bool MySerialPort::isSendingEnable() const
    179. {
    180. return sendingEnable;
    181. }
    182. // Stop the currently sending data operation (don't terminate the thread)
    183. void MySerialPort::stopSending()
    184. {
    185. // If the Sending is not alread active OR the sendThread is not initialized
    186. if (!sendingEnable || !sendThread)
    187. return;
    188. // If the SerialPort is currently sending data, stop
    189. if (sendThread->isRunning())
    190. {
    191. sendThread->stopSending();
    192. //wait(); ??????????
    193. sendThread->wait();
    194. }
    195. }
    196. // Enqueue data to the sendThread queue
    197. // return 1 OK
    198. // return 2 port closed
    199. // return 3 sending operation disable
    200. uchar MySerialPort::sendData(const QByteArray &data)
    201. {
    202. // check the port if is open
    203. if (!isOpen())
    204. return 2;
    205. // check if sending operation is enable
    206. if (!sendingEnable || !sendThread)
    207. return 3;
    208. sendThread->addDataToSend(data);
    209. return 1;
    210. }
    211. /*
    212.   Receive
    213.   */
    214. // Enable the SerialPort to receive data (init the thread)
    215. void MySerialPort::enableReceiving()
    216. {
    217. // If the Receiving is not already active AND the receiveThead is not initialized
    218. if (!receivingEnable && !receiveThread)
    219. {
    220. receiveThread = new ReceiveThread(port);
    221. connect(receiveThread, SIGNAL(dataReceived(const QByteArray &)),
    222. this, SIGNAL(dataReceived(const QByteArray &)));
    223. receivingEnable = true;
    224. }
    225. }
    226. // Disable the SerialPort to receive data (terminate the thread)
    227. void MySerialPort::disableReceiving()
    228. {
    229. // If the Receiving is already active AND there is a receiveThread
    230. if (receivingEnable && receiveThread)
    231. {
    232. delete receiveThread;
    233. receiveThread = NULL;
    234. receivingEnable = false;
    235. }
    236. }
    237. bool MySerialPort::isReceivingEnable() const
    238. {
    239. return receivingEnable;
    240. }
    241. // Stop the currently receiving data operation (don't terminate the thread)
    242. void MySerialPort::stopReceiving()
    243. {
    244. // If the Receiving is not alread active OR the receiveThread is not initialized
    245. if (!receivingEnable || !receiveThread)
    246. return;
    247. // If the SerialPort is currently receiving data, stop
    248. if (receiveThread->isRunning())
    249. {
    250. saveStateReceiveData = false;
    251. receiveThread->stopReceiving();
    252. // wait();
    253. receiveThread->wait();
    254. }
    255. }
    256. // Start the receiving thread
    257. // return 1 OK
    258. // return 2 port closed
    259. // return 3 receiving operation disable
    260. uchar MySerialPort::receiveData()
    261. {
    262. // check the port if is open
    263. if (!isOpen())
    264. return 2;
    265. // check if receiving operation is enable
    266. if (!receivingEnable && !receiveThread)
    267. return 3;
    268. // If the SerialPort receiving thread is not currently active, start it
    269. if (!receiveThread->isRunning())
    270. {
    271. saveStateReceiveData = true;
    272. receiveThread->start();
    273. }
    274. return 1;
    275. }
    276.  
    277. SendThread::SendThread(QextSerialPort &adrPort): port(adrPort)
    278. {
    279. dataToSend.clear();
    280. stopped = false;
    281. }
    282.  
    283. SendThread::~SendThread()
    284. {
    285. if (isRunning())
    286. {
    287. stopSending();
    288. wait();
    289. }
    290. }
    291.  
    292. // Add the data to the Send Queue
    293. void SendThread::addDataToSend(const QByteArray &dataToAdd)
    294. {
    295. QMutexLocker locker(&mutexSend);
    296. for (int i=0; i<dataToAdd.size(); i++)
    297. dataToSend.enqueue(QByteArray(1,dataToAdd.at(i)));
    298. if (!isRunning())
    299. start();
    300. }
    301. // Stop the sending operation
    302. void SendThread::stopSending()
    303. {
    304. stopped = true;
    305. }
    306. // Thread Send Loop
    307. void SendThread::run()
    308. {
    309. QByteArray byteArray;
    310. forever
    311. {
    312. mutexSend.lock();
    313. if (dataToSend.isEmpty() || stopped)
    314. {
    315. mutexSend.unlock();
    316. stopped = false;
    317. break;
    318. }
    319. byteArray = dataToSend.dequeue();
    320. mutexSend.unlock();
    321. port.write(byteArray, 1);
    322. }
    323. }
    324.  
    325. ReceiveThread::ReceiveThread(QextSerialPort &adrPort) : port(adrPort)
    326. {
    327. stopped = false;
    328. }
    329.  
    330. ReceiveThread::~ReceiveThread()
    331. {
    332. if (isRunning())
    333. {
    334. stopReceiving();
    335. wait();
    336. }
    337. }
    338.  
    339. // Stop the sending operation
    340. void ReceiveThread::stopReceiving()
    341. {
    342. stopped = true;
    343. }
    344. // Thread Receive Loop
    345. void ReceiveThread::run()
    346. {
    347. int numBytes = 0;
    348. QByteArray data;
    349. forever
    350. {
    351. if (stopped)
    352. {
    353. stopped = false;
    354. break;
    355. }
    356. numBytes = port.bytesAvailable();
    357. if (numBytes>0)
    358. {
    359. mutexReceive.lock();
    360. data = port.read(numBytes);
    361. mutexReceive.unlock();
    362. emit dataReceived(data);
    363. }
    364. }
    365. }
    To copy to clipboard, switch view to plain text mode 


    Added after 5 minutes:


    OK! Post sourcecode again. I downloaded them from the following link.
    http://www.qtcentre.org/threads/2106...ht=#post103325

    Hi, Lesiok
    Would you like to give some details about why you think these two function make no sense. Thank you.
    Last edited by honestapple; 13th March 2013 at 12:44.

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to solve GUI freezing problem

    Why do you think they do make sense? For instance what do mutexSend and mutexReceive protect?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  8. #8
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to solve GUI freezing problem

    1. You don't need extra run method.
    2. QExtSerialPort is QIODevice so it have signal readyRead().
    3. Why You send only one byte and not all together ?

    Your problem is meaningless program running in circles in both run methods.

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

    Default Re: How to solve GUI freezing problem

    Thank you. It seems that there are something wrong with these two QMutex. The mutexSend is used to protect QQueue dataToSend. For example, if the application need to send some command to the device from the GUI thread using sendData method, the new entered command would disrupt the previous command which was sending. But, there are no need to add mutexSend.lock()/unlock() in run() due to there already has a QMutexLocker in addDataToSend().
    The mutexReceive seems to protect QextSerialPort port to prevent writing the port when reading.
    I still do not understand why these two run() function make no sense. I have test the device using com assistant. It could receive data at a high speed but has no response to user input when receiving. So I tried to seperate the reading and writing operation in two threads as this example did.
    I am a newbie to QT. If I make wrong, please point it out. Thanks a lot.

    In addition, Could anybody access the following blog.
    Qt and serial ports | fede.tft's Blog
    fedetft.wordpress.com/2010/.../qt-and-serial-ports/
    Please paste the content to the board.

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to solve GUI freezing problem

    Quote Originally Posted by honestapple View Post
    The mutexReceive seems to protect QextSerialPort port to prevent writing the port when reading.
    And how do you do that if you don't lock the mutex while sending?

    I still do not understand why these two run() function make no sense.
    Because you are burning cpu cycles like crazy. You don't need those two threads at all. Your program can happily run in one (main) thread. You just need to make sure you try to read something when there is anything to be read.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


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

    Default Re: How to solve GUI freezing problem

    Thank you.
    I knew that the signal readyRead(). It is useful for reading data. I have used this signal on the previous version in which the application has only one thread which process reading and writing operation.When I was receiving data, I could not enter command to order the device to stop uploading data.

    Your last advice remind me perhaps I should buffer the data before process them.


    Added after 15 minutes:


    Yes, If there is only one reading operation, There is no need to use thread. But my trouble is when I am reading, I can not write to it(Perhaps closing it is the only choice). So, I tried to use thread to solve this problem.
    Last edited by honestapple; 13th March 2013 at 14:46.

  12. #12
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to solve GUI freezing problem

    What do you mean by when I am reading, I can not write to it ?

  13. The following user says thank you to Lesiok for this useful post:

    honestapple (15th March 2013)

  14. #13
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to solve GUI freezing problem

    Quote Originally Posted by honestapple View Post
    Yes, If there is only one reading operation, There is no need to use thread.
    No, there is no need to use threads at all here.

    But my trouble is when I am reading, I can not write to it(Perhaps closing it is the only choice).
    No, closing or not closing has nothing to do with it. If you can't write to a port you have been reading from, it means you are doing it wrong (I mean writing).
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  15. The following user says thank you to wysota for this useful post:

    honestapple (15th March 2013)

  16. #14
    Join Date
    Sep 2008
    Location
    Portugal
    Posts
    171
    Thanks
    57
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to solve GUI freezing problem

    Hi

    I'm making some research about serial communication and i came across this post.

    The QextSerialPort (http://sourceforge.net/projects/qext...ce=recommended) is labeled as inactive. Is it a good idea to use it?

    In my case, i ended up installing the QtSerialPort(http://qt-project.org/wiki/QtSerialPort) module and now i'm starting to read somethings about it.

    I want to do some basic serial communication with the Arduino board.

    As i have never done anything like this before, is this a good starting option?

  17. #15
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to solve GUI freezing problem

    Quote Originally Posted by graciano View Post
    Hi

    I'm making some research about serial communication and i came across this post.

    The QextSerialPort (http://sourceforge.net/projects/qext...ce=recommended) is labeled as inactive. Is it a good idea to use it?

    In my case, i ended up installing the QtSerialPort(http://qt-project.org/wiki/QtSerialPort) module and now i'm starting to read somethings about it.

    I want to do some basic serial communication with the Arduino board.

    As i have never done anything like this before, is this a good starting option?
    How about starting your own thread instead of hijacking this one? This thread is about a specific problem which is not "whether I should choose QExtSerialPort or QtSerialPort".
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  18. #16
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to solve GUI freezing problem

    Quote Originally Posted by graciano View Post
    Hi
    I'm making some research about serial communication and i came across this post.
    The QextSerialPort (http://sourceforge.net/projects/qext...ce=recommended) is labeled as inactive. Is it a good idea to use it?
    In my case, i ended up installing the QtSerialPort(http://qt-project.org/wiki/QtSerialPort) module and now i'm starting to read somethings about it.
    I want to do some basic serial communication with the Arduino board.
    As i have never done anything like this before, is this a good starting option?
    Your research is not very accurate. Here is active QextSerialPort. Last version is 1.2 RC.

  19. #17
    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

    [offtop]
    2 Admins,

    Please ban for Taubssmealm or do something else with spam.
    [/offtop]

    2 graciano,

    Please, make another thread for your question. Then we can discuss it.

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

    Default Re: How to solve GUI freezing problem

    Hi,
    Thanks for paticipating this discussion. I think I should explain the problems which I have encountered in detail.
    First, I think that the device transfer data to PC at hight transfer rate is one key point. I have test the device using many com assistants. No one can works well except accessport from SUDT. It can display the received data in hight frame rate, others show me no display, no response, nothing but freezing. I know that some com assistant use a timer to poll the port.This is a effective method at the low data transfer rate. If the data transfer rate is high, I think polling will make PC application blocking or freezing. The better choice will be multithread(I guess the accessport use multithread). The problem with accessport is when it is receiving data, it can't process input commands which are send to port to changing something, sampling rate, data format, data source, restarting data uploading, etc. Even when I try to close the port, the accessport will choke. The correct step to send commands to the device using accessport is:
    1. Stop the device in debug mode, then the accessport will restore responsive.
    2. Send commands to device.
    3. Then, the device will receive the command and do some change.
    I wonder that perhaps it is because that the accessport only have one thread which process reading and writing port simultaneously.
    That why I try to use multithread.
    The above is only my own opinion. If anybody think I am wrong, please point it out. Thank you.
    Then the problem which I encountered in the previous version of the application is that I could not send command when the device is uploading data to the PC. In fact, before the device start to uploading data, the PC should reset the device and shakehand with it. These process all needed reading and writing port, and they works well. But, When the device began to transfer data to PC at high rate, it would be no responsive to click the pushbutton which used to send command to device(I don't want to close the port, I just want to tranfer some command to change the sampling rate or stop transfering, etc).
    I have note that this problems only occur when I tried to display the tranfered data(That is only display them in a textbrowser). If I do nothing including gui operation when receiving data, the GUI will be reponsive to my input(That is I can writing some command to port when it is reading data).
    But, the aim of the application is receiving data at high speed and display them in realtime!!!!
    I have searched on the website, I think the problems stated on the following link are similar to my questions.
    http://stackoverflow.com/questions/1...freezes-my-gui
    http://stackoverflow.com/questions/8...-signals-slots
    Perhaps it is the contradiction of high data transfer rate and slow gui operations which make the GUI has no reponse.

    I still don't understand why wysota said "there is no need to use threads at all here". Does it mean that the Qextserialport has alweady include threads for reading and writing?

    If anybody think I am wrong, Please point it out and give me a little detail. Thank you very much.

  21. #19
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to solve GUI freezing problem

    I have no idea what bearing any of the stuff about some 3rd party software package has to do with your code, threading, Qt GUI responsiveness etc.

    "Very high speed" for a serial port is a mere trickle of data. Compare 115000 bits per second from a "high speed" serial port to 80,000,000+ bits-per-second from a mediocre Ethernet LAN. Qt can saturate the LAN connection over multiple connections without threads... I don't know why you are having difficulty believing that handling data from a few serial ports is hardly an issue.

    Sending a command is simply calling QIODevice::write() on the device. Receiving is merely responding to every time the QIODevice emits readyRead(). Sequencing a handshake is a job for a state machine of some sort. Handling multiple ports is just keeping a list of open QIODevices and reading/writing/tracking state for each. All of the activity is non-blocking, asynchronous, single-threaded, and nobody is suggesting you implement a busy poll of the serial ports.

    If you are trying to get a UI to update itself entirely after each and every sample/byte received, lets say 10000+ times per second, then of course you are going to have issues. This is simply the result of it taking actual time to draw stuff. While the GUI thread is actually drawing it will not respond to user input and threads will not change that; you need to ensure drawing leaves time to process other events. The user cannot possibly follow updates at high rates anyway so you be better off buffering received data and updating the display perhaps 10-20 times a second. Once again this does not require threads.

  22. The following user says thank you to ChrisW67 for this useful post:

    honestapple (15th March 2013)

  23. #20
    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

    @honestapple,

    You have the wrong notion about using streaming I/O. And you're doing it all wrong, and complicates the decision.

    Ideally, in your case there is no need for multi-threading, because the I/O is asynchronous and non-blocking, the engine of which is the Qt event-loop.

    But another thing is that the implementation QExtSerialPort uses "fake" asynchrony.
    For example, when reading data read function can be blocked by PENDING I/O (this is true for Windows implementation),
    so, it can be lead to suspends Qt event-loop in these moments - which, of course, leads to the some GUI freeze.

    To solve problems with asynchronous I/O, I recommend using a different library QtSerialPort
    which does not have these disadvantages.

    In any case, regardless of which library you will be using, you have to do this:

    1. Use one GUI thread, by default
    2. Use async signal/slot approach
    3. Use caching for received data, accumulate it for some time or some size and display or re-draw their by chunk-per-chunk.
    4. Use queue


    You can use the additional thread for:

    1. Processing and converting the data (in case of long-term conversion, etc.)
    2. Move object of serial port to, like:
    Qt Code:
    1. class MySerialPort public BaseAnySerialPortLibraryClass
    2. {
    3. ...
    4. }
    5.  
    6. MyThread::run
    7. {
    8. MySerialPort port;
    9. ...
    10. ...
    11. exec();
    12. }
    To copy to clipboard, switch view to plain text mode 

    because the I/O can stop when you click the mouse on the title bar of window or move the window.
    But in any case, same in a separate thread, use async approach!

  24. The following 2 users say thank you to kuzulis for this useful post:

    graciano (15th March 2013), honestapple (15th March 2013)

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.