Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. it troubles me !!!! QserialPort
Forum Updated to NodeBB v4.3 + New Features

it troubles me !!!! QserialPort

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 4 Posters 1.9k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Q quelle.shen

    a thread problme appear in my code
    STATUS/1 @ init, L120: BaudRate: 230400QObject: Cannot create children for a parent that is in a different thread.
    (Parent is QSerialPort(0x2952c7b8), parent's thread is QThread(0x259e38f0), current thread is QThread(0x14cc2e0)

    my code :
    HardDriver*
    PlatformManager::addHardDriver(uint8_t driver_type, const char* device_port,
    uint32_t baudrate)
    {
    #ifdef QT
    if (driver_type == PlatformManager::SERIAL_DEVICE)
    {

    QThread*     serialEventThread = new QThread;
    QHardDriver* driver            = new QHardDriver(0, device_port, baudrate);
    driver->moveToThread(serialEventThread);
    QObject::connect(serialEventThread, SIGNAL(started()), driver,
                     SLOT(init()));
    QObject::connect(serialEventThread, SIGNAL(finished()), serialEventThread,
                     SLOT(deleteLater()));
    serialEventThread->start();
    QThread::msleep(100);
    return driver;
    

    }


    void
    QHardDriver::init()
    {
    initLock.lock();
    if (this->getDeviceStatus())
    {
    initLock.unlock();
    return;
    }

    port = new QSerialPort(QString(portName));
    if (port != 0)
    {
    if (port->isOpen())
    port->close();
    port->setBaudRate(baudrate);
    port->setParity(QSerialPort::NoParity);
    port->setDataBits(QSerialPort::Data8);
    port->setStopBits(QSerialPort::OneStop);
    port->setFlowControl(QSerialPort::NoFlowControl);
    if (port->open(QIODevice::ReadWrite))
    {
    DSTATUS("port %s open success", port->portName().toLocal8Bit().data());
    setDeviceStatus(true);
    DSTATUS("Read buf size: %d", port->readBufferSize());
    }
    else
    {
    DERROR("fail to open port %s", port->portName().toLocal8Bit().data());
    setDeviceStatus(false);
    }
    DSTATUS("BaudRate: %d", port->baudRate());
    }
    initLock.unlock();
    }


    but run there it throws a problem
    //! Serial Device call: last link in the send pipeline
    DERROR("*****1");
    ans = deviceDriver->send(buf, pHeader->length); // throws Cannot create children for a parent that is in a different thread.
    //(Parent is QSerialPort(0x2952c7b8), parent's thread is
    //QThread(0x259e38f0), current thread is QThread(0x14cc2e0)

    Q Offline
    Q Offline
    quelle.shen
    wrote on last edited by quelle.shen
    #2
    This post is deleted!
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #3

      Hi and welcome to devnet,

      What does happen in deviceDriver->send ?
      Where are you calling if from ?

      What version of Qt are you using ?
      What OS are you running ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1
      • Q Offline
        Q Offline
        quelle.shen
        wrote on last edited by
        #4

        hi ~ thank you first
        it works on windows QT5.1

        HardDriver* deviceDriver;
        QHardDriver::send(const uint8_t* buf, size_t len)
        {
        sendLock.lock();
        size_t sent = 0;
        if (port != 0)
        {
        // if (port->isOpen())
        while (sent != len)
        {
        sent += port->write(reinterpret_cast<const char*>(buf + sent), len);
        port->waitForBytesWritten(2);
        }
        sendLock.unlock();
        return sent;
        }
        else
        {
        sendLock.unlock();
        return 0;
        }
        sendLock.unlock();
        return sent;
        }

        aha_1980A 1 Reply Last reply
        0
        • Q quelle.shen

          hi ~ thank you first
          it works on windows QT5.1

          HardDriver* deviceDriver;
          QHardDriver::send(const uint8_t* buf, size_t len)
          {
          sendLock.lock();
          size_t sent = 0;
          if (port != 0)
          {
          // if (port->isOpen())
          while (sent != len)
          {
          sent += port->write(reinterpret_cast<const char*>(buf + sent), len);
          port->waitForBytesWritten(2);
          }
          sendLock.unlock();
          return sent;
          }
          else
          {
          sendLock.unlock();
          return 0;
          }
          sendLock.unlock();
          return sent;
          }

          aha_1980A Offline
          aha_1980A Offline
          aha_1980
          Lifetime Qt Champion
          wrote on last edited by
          #5

          @quelle.shen said in it troubles me !!!! QserialPort:

          it works on windows QT5.1

          QSerialPort was very new in Qt 5.1. I strongly recommend updating to a newer version.

          That may not solve your problem, but avoid others.

          Qt has to stay free or it will die.

          Q 1 Reply Last reply
          0
          • aha_1980A aha_1980

            @quelle.shen said in it troubles me !!!! QserialPort:

            it works on windows QT5.1

            QSerialPort was very new in Qt 5.1. I strongly recommend updating to a newer version.

            That may not solve your problem, but avoid others.

            Q Offline
            Q Offline
            quelle.shen
            wrote on last edited by
            #6

            @aha_1980
            maybe you are right ,but i have to run it on Qt5.1
            the problem still troubles me !!

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #7

              You seem to move your serial port stuff in another thread and then calling its methods directly, is that the case ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              Q 2 Replies Last reply
              0
              • SGaistS SGaist

                You seem to move your serial port stuff in another thread and then calling its methods directly, is that the case ?

                Q Offline
                Q Offline
                quelle.shen
                wrote on last edited by
                #8

                @SGaist
                yes ,but i dont know how to revision my code.

                1 Reply Last reply
                0
                • SGaistS SGaist

                  You seem to move your serial port stuff in another thread and then calling its methods directly, is that the case ?

                  Q Offline
                  Q Offline
                  quelle.shen
                  wrote on last edited by
                  #9

                  @SGaist
                  why just call port->write() will trows the problem ?
                  i add some code but it doesnt work .
                  i add code :


                  QThread* serialEventThread = new QThread;
                  QHardDriver* driver = new QHardDriver(0, device_port, baudrate);
                  //driver->init();
                  driver->moveToThread(serialEventThread);
                  driver->port->moveToThread(serialEventThread);
                  //Qt:: DirectConnection
                  QObject::connect(serialEventThread, SIGNAL(started()), driver,
                  SLOT(init()));
                  QObject::connect(serialEventThread, SIGNAL(finished()), driver, SLOT(deleteLater()));
                  QObject::connect(serialEventThread, SIGNAL(finished()), serialEventThread,
                  SLOT(deleteLater()));
                  serialEventThread->start();
                  QThread::msleep(100);
                  return driver;


                  1 Reply Last reply
                  0
                  • C Offline
                    C Offline
                    code_fodder
                    wrote on last edited by code_fodder
                    #10

                    @quelle.shen said in it troubles me !!!! QserialPort:

                    QObject::connect(serialEventThread, SIGNAL(started()), driver,
                    SLOT(init()));

                    From our direct messages...

                    hmm.... When you call deviceDriver->send(), I assume that send() is a member of deviceDriver?. But deviceDriver is in a different thread! in addHardDriver() you return a device driver that was moved to a different thread. What you need to do now is create another slot/signal connection to send your write-data to your device driver via a call to a signal. Somthing like: QObject::connect(this, SIGNAL(send_to_driver(QVector data)), driver,SLOT(data_to_send(QVector data))); Then instead of doing driver->write() you do send_to_driver(data). I used QVector in my example - not but you can put what ever Q<data type> you want...

                    Note: You cannot ever safely call members directly in the device driver ever again once you have moved it into another thread :p ... this is exactly what slot/signals are for. Doing so breaks the thread boundaries and Qt rightfully complains. If you call a member function directly then everything that occurs in that function call occurs in the calling thread and not the thread that you moved that class into. Does that make sense?

                    Q 1 Reply Last reply
                    2
                    • C code_fodder

                      @quelle.shen said in it troubles me !!!! QserialPort:

                      QObject::connect(serialEventThread, SIGNAL(started()), driver,
                      SLOT(init()));

                      From our direct messages...

                      hmm.... When you call deviceDriver->send(), I assume that send() is a member of deviceDriver?. But deviceDriver is in a different thread! in addHardDriver() you return a device driver that was moved to a different thread. What you need to do now is create another slot/signal connection to send your write-data to your device driver via a call to a signal. Somthing like: QObject::connect(this, SIGNAL(send_to_driver(QVector data)), driver,SLOT(data_to_send(QVector data))); Then instead of doing driver->write() you do send_to_driver(data). I used QVector in my example - not but you can put what ever Q<data type> you want...

                      Note: You cannot ever safely call members directly in the device driver ever again once you have moved it into another thread :p ... this is exactly what slot/signals are for. Doing so breaks the thread boundaries and Qt rightfully complains. If you call a member function directly then everything that occurs in that function call occurs in the calling thread and not the thread that you moved that class into. Does that make sense?

                      Q Offline
                      Q Offline
                      quelle.shen
                      wrote on last edited by
                      #11

                      @code_fodder
                      thanks reply for my question ,you are right .
                      i think your advice is good way to solve my problem .

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved