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. slots are being called multiple times
Forum Updated to NodeBB v4.3 + New Features

slots are being called multiple times

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 3 Posters 548 Views 4 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.
  • S Offline
    S Offline
    SRaD
    wrote on last edited by
    #1

    I have the following code that gets called whenever a user opens a file, so this code can be called multiple times.

    {   
        QWidget *tab = getTabWidgetByName(name);
    
        mIO = new MIO(this);
        mIO->moveToThread(&mIOThread);
    
        connect(&mIOThread, &QThread::finished, mIO, &QObject::deleteLater);
        connect(this, &MainWindow::startMIO, this, 
        [this] () -> void { mIO->operator()(); }, Qt::UniqueConnection);
        connect(mIO, &MIO::notifyMIOFinished, this,
        &MainWindow::mIOFinished, Qt::UniqueConnection);
    
        mIOThread.start();
    
        emit startMIO();
    }
    

    It works fine until the second time it's called. When run, it appears to be emitting startMIO() twice. The functor mIO->operator()() is certainly called twice somehow and I'm wondering if I'm starting the thread correctly as I call start() on mIOThread. It shouldn't do anything as the constructor is basically empty, and then when emit startMIO() is called, it starts the functor which is where all the work is at.

    I saw several other threads about this, and have added Qt::UniqueConnection, but that doesn't seem to help.

    Here's a bit about the MIO object.

    class MIO : public QObject
    {       
        Q_OBJECT
        
        private:
            MIO(MainWindow *win);
            ~MIO();
    
            void operator()();
        // ...
    }
    
    MIO::MIO(MainWindow *win) : mainWin(win) { }
    
    void MIO::operator()()
    {
        // lots of stuff
    }
    

    Thoughts?

    jeremy_kJ 1 Reply Last reply
    0
    • Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by Chris Kawa
      #2

      It's a problem with your usage of Qt::UniqueConnection in a connect statement with a lambda. Each time a different instance of that lambda object is created so the connection to it is made. The way Qt::UniqueConnection works is it compares the addresses of the objects and function pointers of the signal and slot and doesn't make a connection if all of thouse match something existing.

      In short Qt::UniqueConnection doesn't work with lambdas so replace the lambda with a normal member function.
      Another solution is to store the result of the connect statement ( a QMetaObject::Connection object) and use it to call disconnect after the connection is triggered.

      Also note that your usage of connect is kinda dangerous, You passed this as the first and third parameter so the connection lives as long as this lives. Inside the lambda you are using that mIO object though, that can be destroyed anytime so your app may crash if mIO is deleted and the signal is emited after that. It's better to tie the connection to the object you're using in the lambda, so instead of using this as the third parameter you can use mIO. This way if either this or mIO is deleted the connection will be severed automatically.

      Another consideration is that slots are executed in the thread of the target object, so if you pass this as the third parameter the lambda will be called on the thread that this lives in, not mIO and that's probably not what you want. Passing mIO as the third argument would solve that too.

      1 Reply Last reply
      5
      • S SRaD

        I have the following code that gets called whenever a user opens a file, so this code can be called multiple times.

        {   
            QWidget *tab = getTabWidgetByName(name);
        
            mIO = new MIO(this);
            mIO->moveToThread(&mIOThread);
        
            connect(&mIOThread, &QThread::finished, mIO, &QObject::deleteLater);
            connect(this, &MainWindow::startMIO, this, 
            [this] () -> void { mIO->operator()(); }, Qt::UniqueConnection);
            connect(mIO, &MIO::notifyMIOFinished, this,
            &MainWindow::mIOFinished, Qt::UniqueConnection);
        
            mIOThread.start();
        
            emit startMIO();
        }
        

        It works fine until the second time it's called. When run, it appears to be emitting startMIO() twice. The functor mIO->operator()() is certainly called twice somehow and I'm wondering if I'm starting the thread correctly as I call start() on mIOThread. It shouldn't do anything as the constructor is basically empty, and then when emit startMIO() is called, it starts the functor which is where all the work is at.

        I saw several other threads about this, and have added Qt::UniqueConnection, but that doesn't seem to help.

        Here's a bit about the MIO object.

        class MIO : public QObject
        {       
            Q_OBJECT
            
            private:
                MIO(MainWindow *win);
                ~MIO();
        
                void operator()();
            // ...
        }
        
        MIO::MIO(MainWindow *win) : mainWin(win) { }
        
        void MIO::operator()()
        {
            // lots of stuff
        }
        

        Thoughts?

        jeremy_kJ Offline
        jeremy_kJ Offline
        jeremy_k
        wrote on last edited by jeremy_k
        #3

        edit What @Chris-Kawa said.

        Given the limited context, use of a dedicated QThread seems overly complicated. QtConcurrent::run may be a better solution.

        Asking a question about code? http://eel.is/iso-c++/testcase/

        1 Reply Last reply
        4

        • Login

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