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. Emitting signals from unrelated file causes break

Emitting signals from unrelated file causes break

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 3 Posters 2.5k Views
  • 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.
  • C Offline
    C Offline
    Contempt
    wrote on last edited by Contempt
    #1

    I am attempting to emit multiple of the same signal in one function. Is this not possible, or am I doing it wrong?
    Function with Emitting:

    void mydialog::testfunction(int t, int b)
    {
    	emit testsignal("Hello, World!");
    	Sleep(2000);
    	qDebug("Number: %d/%d", t, b);
    	Sleep(10000);
    	emit testsignal("Hello, World2!");
    }
    

    Calling it

    	QtConcurrent::run(this, &mydialog::testfunction, 9, 8);
    

    Error thrown after the second emit (12 Seconds Later)

    Exception thrown at 0x000000005391BFEE (Qt5Core.dll) in legit.exe: 0xC0000005: Access violation reading location 0x0000000000000023. occurred
    

    If anymore info is needed then please ask.

    1 Reply Last reply
    0
    • B Offline
      B Offline
      bludger
      wrote on last edited by
      #2

      My first bet would be that the instance of mydialog gets deleted/out-of-scope while the signal still must be delivered. But I'm not sure, I need to see some more code then.

      C 2 Replies Last reply
      1
      • B bludger

        My first bet would be that the instance of mydialog gets deleted/out-of-scope while the signal still must be delivered. But I'm not sure, I need to see some more code then.

        C Offline
        C Offline
        Contempt
        wrote on last edited by
        #3
        This post is deleted!
        1 Reply Last reply
        0
        • C Offline
          C Offline
          Contempt
          wrote on last edited by Contempt
          #4
          This post is deleted!
          1 Reply Last reply
          0
          • B bludger

            My first bet would be that the instance of mydialog gets deleted/out-of-scope while the signal still must be delivered. But I'm not sure, I need to see some more code then.

            C Offline
            C Offline
            Contempt
            wrote on last edited by Contempt
            #5

            @bludger With more testing and moving my tests to a new project I think i've come up with a more narrow scenario so you can help me easier. I've now switch from emitting from a closing dialog to emitting from an unrelated file, yet I still hit breakpoints during the emit, but this time even if I emit once.
            emittertest.h

            #include <QObject>
            
            class emittertest : public QObject
            {
            	Q_OBJECT
            public:
            	void fnc(QString r);
            signals:
            	void fnctest(QString);
            private:
            	int value;
            };
            

            emittertest.cpp

            #include "emittertest.h"
            #include "qdebug.h"
            #include <windows.h>
            void emittertest::fnc(QString t)
            {
            	qDebug() << t << "Thanks";
            	//emit fnctest("Word");
            	emit fnctest(QString("Rio"));
            }
            

            My app's .cpp file

            void gq(QString Rex)
            {
            	while (true) {
            		qDebug() << "Name:" << Rex << "Thread:" << QThread::currentThread();
            		Sleep(2000);
            	}
            }
            void QtTestApp::myslot(QString t)
            {
            	qDebug() << "Signal Emitted: " << t;
            }
            QtTestApp::QtTestApp(QWidget *parent)
            	: QMainWindow(parent)
            {
            	ui.setupUi(this);
            	emittertest b;
            	connect(&b, SIGNAL(fnctest(QString)), this, SLOT(myslot(QString)));
            	QFuture<void> f2 = QtConcurrent::run(&b, &emittertest::fnc, QString("NAME"));
            
            }
            

            Error

            Exception thrown at 0x0000000063DFCE09 (Qt5Cored.dll) in QtTestApp.exe: 0xC0000005: Access violation reading location 0x000001FA8800F021. occurred
            
            
            1 Reply Last reply
            0
            • B Offline
              B Offline
              bludger
              wrote on last edited by bludger
              #6

              The emittertest variable gets out of scope before the signal is emitted. Upon connect you use the address of b so Qt's metasystem uses that address until the signal and slot are being disconnected. When leaving the constructor all local variables are going out-of-scope and so does b, meaning that the address of b became invalid.
              A quick fix would be moving the local variable b to be a class member variable. Or making it a pointer instead so the object lives on the heap (make sure you delete it properly to avoid any memory leaks).

              class QtTestApp : public QMainWindow
              {
                 Q_OBJECT
              ....
              private:
                 emittertest m_b;
              }
              

              Or as a pointer: (also a class member)

              class QtTestApp : public QMainWindow
              {
                 Q_OBJECT
              ...
              private:
                 emittertest* m_b;
              }
              
              C 1 Reply Last reply
              4
              • B bludger

                The emittertest variable gets out of scope before the signal is emitted. Upon connect you use the address of b so Qt's metasystem uses that address until the signal and slot are being disconnected. When leaving the constructor all local variables are going out-of-scope and so does b, meaning that the address of b became invalid.
                A quick fix would be moving the local variable b to be a class member variable. Or making it a pointer instead so the object lives on the heap (make sure you delete it properly to avoid any memory leaks).

                class QtTestApp : public QMainWindow
                {
                   Q_OBJECT
                ....
                private:
                   emittertest m_b;
                }
                

                Or as a pointer: (also a class member)

                class QtTestApp : public QMainWindow
                {
                   Q_OBJECT
                ...
                private:
                   emittertest* m_b;
                }
                
                C Offline
                C Offline
                Contempt
                wrote on last edited by
                #7

                @bludger Trying it your way and I get these errors

                Severity	Code	Description	Project	File	Line	Suppression State
                Error	C2065	'm_b': undeclared identifier	QtTestApp	C:\Users\Contempt\source\repos\QtTestApp\QtTestApp\QtTestApp.cpp	21	
                
                Severity	Code	Description	Project	File	Line	Suppression State
                Error	C4430	missing type specifier - int assumed. Note: C++ does not support default-int	QtTestApp	c:\users\contempt\source\repos\qttestapp\qttestapp\QtTestApp.h	15	
                
                Severity	Code	Description	Project	File	Line	Suppression State
                Error	C3646	'm_b': unknown override specifier	QtTestApp	c:\users\contempt\source\repos\qttestapp\qttestapp\QtTestApp.h	15	
                
                
                

                My QtTestApp.h

                class QtTestApp : public QMainWindow
                {
                	Q_OBJECT
                
                public:
                	QtTestApp(QWidget *parent = Q_NULLPTR);
                	private slots:
                	void myslot(QString);
                private:
                	emittertest m_b;
                	Ui::QtTestAppClass ui;
                };
                

                And I can not run emittertest::fnc() in a QtConcurrent thread anymore.

                1 Reply Last reply
                0
                • VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by
                  #8

                  It's still a race condition as there is nothing stopping your QMainWindow destroying before QtConcurrent::run finished. There is a way of making it work even with QtConcurrent but it's harder than just using QThread: see https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

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

                    @Contempt I guess you forgot to include the emittertest header file in QtTestApp.h. As long as it is not known within the QtTestApp header you will get the errors you're reporting.

                    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