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.8k 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 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 Offline
                  jsulmJ Offline
                  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