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
Forum Updated to NodeBB v4.3 + New Features

Emitting signals from unrelated file causes break

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 3 Posters 2.4k 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