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. QSerialPort with no GUI: QObject::startTimer: Timers can only be used with threads started with QThread
Forum Updated to NodeBB v4.3 + New Features

QSerialPort with no GUI: QObject::startTimer: Timers can only be used with threads started with QThread

Scheduled Pinned Locked Moved Unsolved General and Desktop
17 Posts 6 Posters 1.9k Views 1 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.
  • B Offline
    B Offline
    bast236
    wrote on last edited by
    #1

    I'm doing a DLL with no GUI (TEMPLATE = lib), using QSerialPort. I don't create threads and I don't need any: I have no GUI and having a blocking serial port operation is no problem, it is what I want.

    When doing:

    while (!serial_uart->isWritable());
    while (!serial_uart->write(frame));
    

    I get:

    QObject::startTimer: Timers can only be used with threads started with QThread

    How to use QSerialPort in a library without GUI without triggering this error?

    Note: I first thought the problem was coming from serial_uart->waitForReadyRead(timeout) but even without this and only serial_uart->write() I already have this problem.

    JonBJ 1 Reply Last reply
    1
    • B bast236

      I'm doing a DLL with no GUI (TEMPLATE = lib), using QSerialPort. I don't create threads and I don't need any: I have no GUI and having a blocking serial port operation is no problem, it is what I want.

      When doing:

      while (!serial_uart->isWritable());
      while (!serial_uart->write(frame));
      

      I get:

      QObject::startTimer: Timers can only be used with threads started with QThread

      How to use QSerialPort in a library without GUI without triggering this error?

      Note: I first thought the problem was coming from serial_uart->waitForReadyRead(timeout) but even without this and only serial_uart->write() I already have this problem.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @bast236
      Did you maybe try out https://doc.qt.io/qt-6/qtserialport-cwritersync-example.html, which claims to work with no GUI/event loop?

      1 Reply Last reply
      0
      • B Offline
        B Offline
        bast236
        wrote on last edited by bast236
        #3

        @JonB I'm doing a DLL lib without QCoreApplication. I'm really using a minimal example:

        test.cpp

        #include "test.h"
        extern "C" {
            __declspec(dllexport) Test* new_Test() { return new Test(); }
            __declspec(dllexport) void DoTest(Test *t) { t->DoTest(); }
        }
        Test::Test() :QObject()
        {
            qDebug("Hello");
        }
        void Test::DoTest()
        {
            this->serialport = new QSerialPort();
            this->serialport ->setPortName("COM12");
            this->serialport->setBaudRate(QSerialPort::Baud19200);
            this->serialport->open(QIODevice::ReadWrite);
            while (!this->serialport->isWritable());
            while (!this->serialport->write("hello"));
        }
        

        test.h

        #include <QSerialPort>
        class Test : public QObject
        {
            Q_OBJECT
        public:
            Test();
            void DoTest();
            QSerialPort *serialport;
        };
        

        test.pro

        TEMPLATE = lib
        TARGET = test
        QT += serialport
        INCLUDEPATH += .
        HEADERS += test.h
        SOURCES += test.cpp
        

        When I call the release/test.dll from Python I have this:

        from ctypes import *
        dll = CDLL(r"release\test.dll")
        dll.new_Test.restype = c_void_p
        dll.new_Test.argtypes = []
        dll.DoTest.restype = None
        dll.DoTest.argtypes = [c_void_p]
        t = dll.new_Test()
        dll.DoTest(t)
        

        Hello

        QObject::startTimer: Timers can only be used with threads started with QThread

        1 Reply Last reply
        0
        • Christian EhrlicherC Online
          Christian EhrlicherC Online
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          You need a running Q(Core)Application.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          V 1 Reply Last reply
          0
          • B Offline
            B Offline
            bast236
            wrote on last edited by bast236
            #5

            @Christian-Ehrlicher Thank you. Is this possible if I just want to make a small DLL without GUI?
            How would you modify my test.cpp to do so?

            Christian EhrlicherC 1 Reply Last reply
            0
            • B bast236

              @Christian-Ehrlicher Thank you. Is this possible if I just want to make a small DLL without GUI?
              How would you modify my test.cpp to do so?

              Christian EhrlicherC Online
              Christian EhrlicherC Online
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @bast236 said in QSerialPort with no GUI: QObject::startTimer: Timers can only be used with threads started with QThread:

              How would you modify my test.cpp to do so?

              You need to make sure a Q(Core)Application instance is available. If there is none you have to create/destroy it by yourself.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              1 Reply Last reply
              0
              • B Offline
                B Offline
                bast236
                wrote on last edited by bast236
                #7

                @Christian-Ehrlicher Is it adapted even for a simple DLL without GUI?
                When looking at https://code.qt.io/cgit/qt/qtserialport.git/tree/examples/serialport/cwritersync/main.cpp?h=6.3#n59 we see it lives in a main() with argc, argv:

                QCoreApplication coreApplication(argc, argv);
                

                but for a DLL without main how would you do this?

                (Also, in this code example, the variable coreApplication is never used later in the code).

                Christian EhrlicherC 1 Reply Last reply
                0
                • B bast236

                  @Christian-Ehrlicher Is it adapted even for a simple DLL without GUI?
                  When looking at https://code.qt.io/cgit/qt/qtserialport.git/tree/examples/serialport/cwritersync/main.cpp?h=6.3#n59 we see it lives in a main() with argc, argv:

                  QCoreApplication coreApplication(argc, argv);
                  

                  but for a DLL without main how would you do this?

                  (Also, in this code example, the variable coreApplication is never used later in the code).

                  Christian EhrlicherC Online
                  Christian EhrlicherC Online
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @bast236 said in QSerialPort with no GUI: QObject::startTimer: Timers can only be used with threads started with QThread:

                  without main how would you do this?

                  If there is none you have to create/destroy it by yourself.

                  Check if there is an instance, if not create one - creating and deleting an object is basic c++ stuff.

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  1 Reply Last reply
                  0
                  • B Offline
                    B Offline
                    bast236
                    wrote on last edited by bast236
                    #9

                    @Christian-Ehrlicher Yes I know how to do this, but the question is: what argc, argv to give to the QCoreApplication constructor? Since it's a DLL with no argc, argv, it does not make sense here.

                    Warning: The data referred to by argc and argv must stay valid for the entire lifetime of the QCoreApplication object. In addition, argc must be greater than zero and argv must contain at least one valid character string.

                    Here how could I give a argument count greater than zero?

                    It's not a .exe file, it's a DLL, there is no argc, argv.

                    jsulmJ 1 Reply Last reply
                    0
                    • B bast236

                      @Christian-Ehrlicher Yes I know how to do this, but the question is: what argc, argv to give to the QCoreApplication constructor? Since it's a DLL with no argc, argv, it does not make sense here.

                      Warning: The data referred to by argc and argv must stay valid for the entire lifetime of the QCoreApplication object. In addition, argc must be greater than zero and argv must contain at least one valid character string.

                      Here how could I give a argument count greater than zero?

                      It's not a .exe file, it's a DLL, there is no argc, argv.

                      jsulmJ Online
                      jsulmJ Online
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @bast236 said in QSerialPort with no GUI: QObject::startTimer: Timers can only be used with threads started with QThread:

                      what argc, argv to give to the QCoreApplication constructor?

                      argc/argv you got in your main, pass those to your DLL

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      1
                      • Christian EhrlicherC Online
                        Christian EhrlicherC Online
                        Christian Ehrlicher
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        ... and make sure the argc parameter goes not out of scope as long as Q(Core)Application lives since Q(Core)Application takes this parameter as reference - otherwise Q(Core)Application will work on a dangling reference afterwards.

                        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                        Visit the Qt Academy at https://academy.qt.io/catalog

                        1 Reply Last reply
                        1
                        • B Offline
                          B Offline
                          bast236
                          wrote on last edited by bast236
                          #12

                          @jsulm

                          argc/argv you got in your main, pass those to your DLL

                          This would not really work in my context: I am coding a DLL plugin for an external .exe application that I don't create myself.
                          This .exe (not created by me) calls some functions of the DLL with a standardized API, and usually this pre-made API won't be made to pass the .exe's argc/argv to the DLL functions.

                          So the only solution I see is to do a fake dummy argc/argv:

                          int argc = 1;
                          const char* argv[] = { "test.exe" };
                          this->core_app = new QCoreApplication(argc, (char **) argv);
                          

                          Do you think it is a valid solution @jsulm ?

                          1 Reply Last reply
                          0
                          • Christian EhrlicherC Christian Ehrlicher

                            You need a running Q(Core)Application.

                            V Offline
                            V Offline
                            Violet Giraffe
                            wrote on last edited by
                            #13

                            @Christian-Ehrlicher said in QSerialPort with no GUI: QObject::startTimer: Timers can only be used with threads started with QThread:

                            You need a running Q(Core)Application.

                            That is not enough, unless you're only using the main thread. I want to use QSerialPort in my own std::thread and I get the same error even if I do create and exec() QCoreApplication on the main thread. So the error message is quite literal. I was hoping there is some workaround to not use parts of QSerialPort that need a Qt thread, but I guess there's no way and I should use another serial library instead (at which point I might as well remove Qt from the project entirely).

                            Christian EhrlicherC 1 Reply Last reply
                            0
                            • V Violet Giraffe

                              @Christian-Ehrlicher said in QSerialPort with no GUI: QObject::startTimer: Timers can only be used with threads started with QThread:

                              You need a running Q(Core)Application.

                              That is not enough, unless you're only using the main thread. I want to use QSerialPort in my own std::thread and I get the same error even if I do create and exec() QCoreApplication on the main thread. So the error message is quite literal. I was hoping there is some workaround to not use parts of QSerialPort that need a Qt thread, but I guess there's no way and I should use another serial library instead (at which point I might as well remove Qt from the project entirely).

                              Christian EhrlicherC Online
                              Christian EhrlicherC Online
                              Christian Ehrlicher
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              @Violet-Giraffe said in QSerialPort with no GUI: QObject::startTimer: Timers can only be used with threads started with QThread:

                              std::thread and I get the same error

                              As I said you need a running event loop. Of course this event loop must be in the same thread as QSerialPort. How should it work otherwise...

                              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                              Visit the Qt Academy at https://academy.qt.io/catalog

                              V 1 Reply Last reply
                              0
                              • Christian EhrlicherC Christian Ehrlicher

                                @Violet-Giraffe said in QSerialPort with no GUI: QObject::startTimer: Timers can only be used with threads started with QThread:

                                std::thread and I get the same error

                                As I said you need a running event loop. Of course this event loop must be in the same thread as QSerialPort. How should it work otherwise...

                                V Offline
                                V Offline
                                Violet Giraffe
                                wrote on last edited by Violet Giraffe
                                #15

                                QSerialPort should not require an event loop, that's how. It's stupid design. Or it should route through the main loop (i. e. the one in the main thread). But it is what it is, I get it.

                                J.HilkJ Christian EhrlicherC 2 Replies Last reply
                                0
                                • V Violet Giraffe

                                  QSerialPort should not require an event loop, that's how. It's stupid design. Or it should route through the main loop (i. e. the one in the main thread). But it is what it is, I get it.

                                  J.HilkJ Offline
                                  J.HilkJ Offline
                                  J.Hilk
                                  Moderators
                                  wrote on last edited by
                                  #16

                                  @Violet-Giraffe said in QSerialPort with no GUI: QObject::startTimer: Timers can only be used with threads started with QThread:

                                  QSerialPort should not require an event loop, that's how. It's stupid design. But it is what it is, I get it.

                                  it doesn't that's why the "waitForXXX" functions exist. So that QSerialPort can be used in non event loop environments


                                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                  Q: What's that?
                                  A: It's blue light.
                                  Q: What does it do?
                                  A: It turns blue.

                                  1 Reply Last reply
                                  3
                                  • V Violet Giraffe

                                    QSerialPort should not require an event loop, that's how. It's stupid design. Or it should route through the main loop (i. e. the one in the main thread). But it is what it is, I get it.

                                    Christian EhrlicherC Online
                                    Christian EhrlicherC Online
                                    Christian Ehrlicher
                                    Lifetime Qt Champion
                                    wrote on last edited by
                                    #17

                                    @Violet-Giraffe please show me one framework which works without an event loop when doing async stuff. Or blocks the execution as @J-Hilk showed you.

                                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                    Visit the Qt Academy at https://academy.qt.io/catalog

                                    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