Results 1 to 5 of 5

Thread: Emit signal outside run() in QThread

  1. #1
    Join Date
    Jan 2011
    Location
    Australia
    Posts
    44
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60

    Default Emit signal outside run() in QThread

    Hello everyone,

    I have three class
    Server : QTcpServer
    ServerThread : QThread

    and main class (GUI)

    Have a look at my code.
    Qt Code:
    1. #ifndef SERVER_H
    2. #define SERVER_H
    3.  
    4. #include <QTcpServer>
    5. #include <QByteArray>
    6.  
    7. class ServerThread;
    8. class Dialog;
    9.  
    10. class Server : public QTcpServer
    11. {
    12. Q_OBJECT
    13. private:
    14. Dialog *parent_;
    15. public:
    16. explicit Server(Dialog *parent);
    17. void incomingConnection(int socketDescriptor
    18. );
    19. void startServer(int);
    20. signals:
    21. void received(QString data);
    22. public slots:
    23. void onreceived(QString data);
    24. };
    25.  
    26. #endif // SERVER_H
    27.  
    28. #ifndef SERVERTHREAD_H
    29. #define SERVERTHREAD_H
    30.  
    31. #include <QThread>
    32. #include <QByteArray>
    33. #include "dialog.h"
    34. class QTcpSocket;
    35.  
    36. class ServerThread : public QThread
    37. {
    38. Q_OBJECT
    39. private:
    40. int socketDescriptor_;
    41.  
    42. Dialog *parent_;
    43. public:
    44. explicit ServerThread(int socketDescriptor,Dialog *parent);
    45. QTcpSocket *tcpSocket;
    46. void run(void);
    47. bool emit_signal;
    48. signals:
    49. void received_sgl(QString str);
    50. public slots:
    51. void received(void);
    52. void disconnected(void);
    53.  
    54. };
    55.  
    56. #endif // SERVERTHREAD_H
    57.  
    58. #ifndef DIALOG_H
    59. #define DIALOG_H
    60.  
    61. #include <QDialog>
    62. #include <QString>
    63. #include <QByteArray>
    64. namespace Ui {
    65. class Dialog;
    66. }
    67.  
    68. class QTcpSocket;
    69. class Server;
    70. class Dialog : public QDialog
    71. {
    72. Q_OBJECT
    73.  
    74. public:
    75. explicit Dialog(QWidget *parent = 0);
    76. ~Dialog();
    77. QTcpSocket *socket;
    78. Server *s;
    79.  
    80. void update(QString s);
    81.  
    82. private slots:
    83. void on_pushButton_2_clicked();
    84. void on_pushButton_clicked();
    85. void received();
    86. void rcd_(QByteArray arr);
    87.  
    88.  
    89. signals:
    90. private:
    91. Ui::Dialog *ui;
    92. };
    93.  
    94. #endif // DIALOG_H
    To copy to clipboard, switch view to plain text mode 


    and following implementation
    Qt Code:
    1. SERVER.cpp
    2.  
    3. #include "server.h"
    4. #include "serverthread.h"
    5. #include <QDebug>
    6. Server::Server(Dialog *parent) :
    7. QTcpServer(parent),parent_(parent)
    8. {
    9. }
    10. void Server::startServer(int port)
    11. {
    12.  
    13. this->listen(QHostAddress::Any,port);
    14. qDebug()<<"listening!";
    15. }
    16.  
    17. void Server::incomingConnection(int socketDescriptor)
    18. {
    19. qDebug()<<"Server::incomming connection";
    20. ServerThread *thread=new ServerThread(socketDescriptor,parent_);
    21. connect(thread,SIGNAL(received_sgl(QString)),this,SLOT(onreceived(QString)));
    22. connect(thread,SIGNAL(finished()),thread,SLOT(deleteLater()));
    23. thread->start();
    24.  
    25. }
    26.  
    27.  
    28. void Server::onreceived(QString data)
    29. {
    30. qDebug()<<"updating...::::"<<QString(data);
    31. parent_->update("updating..."+data);
    32.  
    33.  
    34. }
    35.  
    36. ServerThread.cpp
    37. #include "serverthread.h"
    38. #include <QTcpSocket>
    39. #include <QDebug>
    40.  
    41.  
    42.  
    43. ServerThread::ServerThread(int socketDescriptor,Dialog *parent) :
    44. QThread(parent),socketDescriptor_(socketDescriptor),parent_(parent)
    45. {
    46.  
    47. }
    48.  
    49.  
    50.  
    51.  
    52. void ServerThread::run()
    53. {
    54. tcpSocket=new QTcpSocket(parent_);
    55. tcpSocket->setSocketDescriptor(socketDescriptor_);
    56.  
    57. connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(received()),Qt::DirectConnection);
    58. connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(disconnected()),Qt::DirectConnection);
    59.  
    60. qDebug()<<"ServerThread::run";
    61.  
    62. exec();
    63. }
    64.  
    65.  
    66. void ServerThread::received()
    67. {
    68.  
    69. qDebug()<<"ServerThread::received()"<<QString(tcpSocket->readAll());
    70.  
    71. emit received_sgl(QString(tcpSocket->readAll()));
    72.  
    73. if (tcpSocket->isWritable())
    74. {
    75. tcpSocket->write(QByteArray("writing..."));
    76.  
    77. }
    78. }
    79.  
    80. void ServerThread::disconnected()
    81. {
    82. tcpSocket->deleteLater(); //delete tcpSocket once exit() for thread is executed
    83. exit(); //exit the thread
    84. }
    85.  
    86. Dialog.cpp
    87.  
    88. #include "dialog.h"
    89. #include "ui_dialog.h"
    90. #include "server.h"
    91.  
    92. #include <QTcpSocket>
    93. #include <QDebug>
    94. Dialog::Dialog(QWidget *parent) :
    95. QDialog(parent),
    96. ui(new Ui::Dialog)
    97. {
    98. ui->setupUi(this);
    99.  
    100. s=new Server(this);
    101. socket=new QTcpSocket(this);
    102.  
    103. QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(received()));
    104. QObject::connect(s, SIGNAL(received(QByteArray)), this, SLOT(rcd_(QByteArray)));
    105.  
    106. }
    107.  
    108. Dialog::~Dialog()
    109. {
    110. delete ui;
    111. }
    112. void Dialog::rcd_(QByteArray arr)
    113. {
    114. ui->lblmsg->setText(QString(arr));
    115. qDebug()<<QString(arr);
    116. }
    117.  
    118. void Dialog::on_pushButton_2_clicked()
    119. {
    120.  
    121.  
    122. s->startServer(ui->lineEdit->text().toInt());
    123. ui->lineEdit->setEnabled(false);
    124.  
    125. }
    126. void Dialog::received()
    127. {
    128. qDebug()<<"received by client";
    129.  
    130. update(QString(socket->readAll()));
    131.  
    132. }
    133.  
    134. void Dialog::on_pushButton_clicked()
    135. {
    136. qDebug()<<"sending...";
    137. socket->open(QAbstractSocket::ReadWrite);
    138.  
    139. socket->connectToHost(ui->lineEdit_3->text(),ui->lineEdit_2->text().toInt());
    140. socket->write("write now");
    141.  
    142. socket->close();
    143. // socket->close();
    144. //delete socket;
    145.  
    146. }
    147.  
    148. void Dialog::update(QString s)
    149. {
    150. ui->lblmsg->setText(s);
    151. }
    To copy to clipboard, switch view to plain text mode 


    it works fine and emits signal and is caught my slot. But by the time slot catches the signal "data" is already lost

    could someone spot out problem?

    (if i need to emit signal in run() i have tried to do it using boolean flag but didn't quite work)


    Thank you so much for your time
    Life is like a dream, sometimes it is good and somtimes it is bad, but in the end it is over

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,658
    Thanks
    13
    Thanked 1,594 Times in 1,522 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Emit signal outside run() in QThread

    I really don't know why people insist on using threads in (presumably) low volume servers. It only serves to complicate.

    Anyway. At line 69 of your implementation you read all the available data to dump to debug. When you then try to read all the same data again at line 71 it is hardly surprising that there is no more.

  3. #3
    Join Date
    Jan 2011
    Location
    Australia
    Posts
    44
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60

    Default Re: Emit signal outside run() in QThread

    Thanks

    Yea I normally dont do that, this was just a test example.

    Now i have a little problem. If i run in debug mode it runs fine and if i run it in non-debug mode that means just play button in qt creator it crashes with Visual C++ runtime error

    Any idea why?
    Life is like a dream, sometimes it is good and somtimes it is bad, but in the end it is over

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

    Default Re: Emit signal outside run() in QThread

    Most probably an uninitialized pointer somewhere.
    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
    Jan 2011
    Location
    Australia
    Posts
    44
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60

    Default Re: Emit signal outside run() in QThread

    Just for anyone curious about answer to this is:

    I used signal and slot mechanism in MyThread : QThread

    Additionally, the crash was because of DirectConnection in signal (line: 57)
    Life is like a dream, sometimes it is good and somtimes it is bad, but in the end it is over

Similar Threads

  1. How to decide which SIGNAL to emit?
    By TheIndependentAquarius in forum Qt Programming
    Replies: 2
    Last Post: 22nd November 2011, 15:09
  2. Replies: 2
    Last Post: 3rd May 2011, 20:22
  3. Replies: 3
    Last Post: 7th April 2011, 11:09
  4. QThread don' stop (or the signal don't emit)
    By msdark in forum Qt Programming
    Replies: 1
    Last Post: 10th March 2011, 23:51
  5. emit a signal
    By Morea in forum Qt Programming
    Replies: 2
    Last Post: 27th February 2006, 11:14

Tags for this Thread

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.