Results 1 to 6 of 6

Thread: QTcpSocket parent-child constructor woes (also cross-thread talk)

  1. #1
    Join Date
    May 2014
    Posts
    16
    Qt products
    Qt4
    Platforms
    Windows

    Default QTcpSocket parent-child constructor woes (also cross-thread talk)

    I spent about 10 hours yesterday with Qt stuff and I'm kind of exhausted, so I'm really bad at searching for answers on my own right now. If you guys could help me out, that would be appreciated.

    The basic idea is that I want to start up TCP socket communication (it reads accelerometer data from a microcontroller), and I want to start up a QGLWidget to do other stuff. The QTcpSocket starts up in it's own thread (apparently on its own) though and can't be set as the QObject child of the QGLWidget, or at least that was my conclusion based on the threading errors that popped up. Then I tried to get a basic QTcpSocket to work and it broke. I am failing here.

    What is wrong with the following code? I spits out the following runtime error:

    Qt Code:
    1. QObject: Cannot create children for a parent that is in a different thread.
    2. (Parent is in my_TCP_Q_socket_with_readyRead(*some address*), parent's thread is QThread(*some address*), current thread is QThread(*some address*)
    To copy to clipboard, switch view to plain text mode 

    For the record, I am I using QtCreator now. I figured out how to move between Visual Studio and QtCreator, so I just picked one.
    Here is main.cpp:
    Qt Code:
    1. #include <QTcpSocket>
    2. #include <QObject>
    3.  
    4. #include <iostream>
    5. using std::cout;
    6. using std::endl;
    7.  
    8.  
    9. class my_TCP_Q_socket_with_readyRead : public QObject
    10. {
    11. public:
    12. explicit my_TCP_Q_socket_with_readyRead(QObject *parent = 0) :
    13. QObject(parent)
    14. {
    15. m_socket_ptr = new QTcpSocket(this); // complains about parent-child threading
    16. //m_socket_ptr = new QTcpSocket(0); // no error (??but what is it doing? it is silent??)
    17. }
    18.  
    19.  
    20. private:
    21. Q_OBJECT
    22.  
    23. QTcpSocket *m_socket_ptr;
    24. };
    25.  
    26.  
    27. #include "main.moc"
    28.  
    29. int main(int argc, char *argv[])
    30. {
    31. my_TCP_Q_socket_with_readyRead s;
    32.  
    33. return 0;
    34. }
    To copy to clipboard, switch view to plain text mode 

    What am I doing wrong? I found that this code doesn't complain if I provide a 0 (integer zero) as the argument to the QTcpSocket, but why?


    As a related followup question, is it possible to use signals and slots to pass data from the thread that has the QTcpSocket to the thread that contains my QGLWidget? I think I can figure out how to make signals and slots work to call a function in QGLWidget once my custom QTcpSocket object is done reading data, but I don't know how to pass data from one to the other. Or am I missing the way this works? I haven't discovered how or when Qt starts threads on its own (which it clearly does considering that the error shown above specifies two threads).
    Last edited by amdreallyfast; 25th May 2014 at 17:18. Reason: updated contents; added in-code note of what is good and what is bad

  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: QTcpSocket parent-child constructor woes (also cross-thread talk)

    Quote Originally Posted by amdreallyfast View Post
    What am I doing wrong?
    No idea, your code is obviously more than what you have posted.

    Quote Originally Posted by amdreallyfast View Post
    I found that this code doesn't complain if I provide a 0 (integer zero) as the argument to the QTcpSocket, but why?
    0 is the value of a null pointer, so no parent.

    Quote Originally Posted by amdreallyfast View Post
    As a related followup question, is it possible to use signals and slots to pass data from the thread that has the QTcpSocket to the thread that contains my QGLWidget?
    Yes, though you most likely don't need threads here at all (Qt's networking code operates event based by default).

    Quote Originally Posted by amdreallyfast View Post
    I think I can figure out how to make signals and slots work to call a function in QGLWidget once my custom QTcpSocket object is done reading data, but I don't know how to pass data from one to the other.
    Signals can carry arguments. Since it is unlikely that the data received via socket is directly usable by a QGLWidget, you will probably want to receive it in a slot that interprets the data.
    Can of course be in a slot of a class derived from QGLWidget, though it is probably cleaner to use a dedicated connection/data handling object instead.

    Cheers,
    _

  3. #3
    Join Date
    May 2014
    Posts
    16
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTcpSocket parent-child constructor woes (also cross-thread talk)

    ...your code is obviously more than what you have posted.
    Nope. That code is all my test code in it's entirety. I just pasted it back into QtCreator and it gave me the same error. Does it work for you?

  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: QTcpSocket parent-child constructor woes (also cross-thread talk)

    Ah, then you need to create a Qt application object, e.g. a QCoreApplication instance, before creating the QTcpSocket,

    Cheers,
    _

  5. #5
    Join Date
    May 2014
    Posts
    16
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTcpSocket parent-child constructor woes (also cross-thread talk)

    Funny thing about that: I tried both the QApplication (that one took awhile to figure out the .pro file) and QCoreApplication, and they both give the same error. The error comes from the QTcpSocket constructor, not from the application. The bizarre part is that it seems that the QTcpSocket was created anyway, and while QCoreApplication ignores it, Qapplication goes ahead anyway and is happy with my QObject::connect(...) stuff and it works, so I don't know what it's complaining about.

    Bottom line: My code works, but something, somewhere, is still not ok.

    Note: This is a QConsole project. Here is my .pro file:
    Qt Code:
    1. QT += core gui network
    2.  
    3. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    4.  
    5. TARGET = testing_1
    6. CONFIG += console
    7. CONFIG -= app_bundle
    8.  
    9. TEMPLATE = app
    10.  
    11.  
    12. SOURCES += main.cpp
    13.  
    14. HEADERS +=
    15.  
    16.  
    17. INCLUDEPATH += tmp/moc/release_shared
    18.  
    19. unix|win32: LIBS += -L$$PWD/../../../../../Qt/4.8.5/lib/ -lQtCore4
    20.  
    21. INCLUDEPATH += $$PWD/../../../../../Qt/4.8.5/include
    22. DEPENDPATH += $$PWD/../../../../../Qt/4.8.5/include
    To copy to clipboard, switch view to plain text mode 


    Here is my latest experimental code if you're interested:
    Qt Code:
    1. #include <QApplication>
    2. #include <QtCore/QCoreApplication>
    3.  
    4. #include <iostream>
    5. using std::cout;
    6. using std::endl;
    7.  
    8. #include <QtDebug>
    9. #include <QObject>
    10. #include <QtNetwork/QTcpSocket>
    11.  
    12.  
    13. class my_TCP_Q_socket_with_readyRead : public QObject
    14. {
    15. public:
    16. explicit my_TCP_Q_socket_with_readyRead(QObject *parent = 0) :
    17. QObject(parent)
    18. {
    19. // ??why are you not ok taking "this" as an argument ?!
    20. m_socket_ptr = new QTcpSocket(this);
    21.  
    22. m_socket_ptr->connectToHost("10.10.10.126", 5);
    23. if (!(m_socket_ptr->waitForConnected((5000))))
    24. {
    25. qDebug() << "not connected";
    26. m_socket_ptr = NULL;
    27. }
    28. else
    29. {
    30. qDebug() << "connected";
    31. }
    32.  
    33. QObject::connect(
    34. m_socket_ptr,
    35. SIGNAL(readyRead()),
    36. this,
    37. SLOT(read_it()));
    38. }
    39.  
    40.  
    41. // http://qt-project.org/wiki/Qt_for_beginners_Signals_and_slots_2
    42. // "Even if the signal is declared as a method, there is no
    43. // need to implement it. The meta-object compiler is used to
    44. // do this."
    45. Q_SIGNAL void done_reading(int num);
    46.  
    47. private:
    48. Q_OBJECT
    49.  
    50. QTcpSocket *m_socket_ptr;
    51. QByteArray m_arr;
    52.  
    53. Q_SLOT void read_it()
    54. {
    55. static int read_count = 0;
    56. qint64 bytes_available = m_socket_ptr->bytesAvailable();
    57.  
    58. if (bytes_available > 0)
    59. {
    60. read_count += 1;
    61.  
    62. qDebug() << "Reading '" << bytes_available << "' bytes";
    63. m_arr = m_socket_ptr->readAll();
    64. qDebug() << m_arr;
    65. }
    66.  
    67. emit done_reading(read_count);
    68. }
    69. };
    70.  
    71.  
    72. class my_class : public QObject
    73. {
    74. public:
    75. explicit my_class(QObject *parent = 0) :
    76. QObject(parent)
    77. {
    78.  
    79. }
    80.  
    81. Q_SLOT void say_something(int num)
    82. {
    83. cout << "hey there! number is '" << num << "'" << endl;
    84. }
    85.  
    86. private:
    87. Q_OBJECT
    88. };
    89.  
    90.  
    91. #include "main.moc"
    92.  
    93. int main(int argc, char *argv[])
    94. {
    95. int app_ret_val = 0;
    96. //QApplication app(argc, argv);
    97. QCoreApplication app(argc, argv);
    98.  
    99. my_TCP_Q_socket_with_readyRead s;
    100. my_class mc;
    101.  
    102. QObject::connect(&s, SIGNAL(done_reading(int)), &mc, SLOT(say_something(int)));
    103.  
    104. app_ret_val = app.exec();
    105.  
    106.  
    107. return app_ret_val;
    108. }
    To copy to clipboard, switch view to plain text mode 

    I've been trying to hunt down how the basic QTcpSocket constructor is supposed work with the "this" argument. It is supposed to "just work" from the demos that I have seen, so I don't know where to to do when it doesn't work. Any more ideas?

  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: QTcpSocket parent-child constructor woes (also cross-thread talk)

    Have you tried not using the blocking I/O methods, i.e. any of the "waitFor..." ones?

    Cheers,
    _

Similar Threads

  1. Start a thread automatic at start
    By ralphot in forum Qt Programming
    Replies: 3
    Last Post: 10th July 2013, 16:54
  2. thread->start() does not work ?
    By ErrMania in forum Newbie
    Replies: 3
    Last Post: 20th November 2011, 12:08
  3. Replies: 3
    Last Post: 19th January 2010, 21:26
  4. Replies: 16
    Last Post: 7th October 2009, 09:17
  5. How to start a thread (inline)
    By DiamonDogX in forum Qt Programming
    Replies: 4
    Last Post: 28th May 2009, 22:53

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.