Qt5: хотя сигнал подключен, сигнал испущен, но слот не вызывается - PullRequest
0 голосов
/ 13 января 2019

Итак, у меня есть класс Qt MyQtClass и унаследованный от QOject класс Sender. Я хочу получить доступ к пользовательскому интерфейсу из класса Sender (который, кстати, состоит только из статических членов), поэтому я настроил функции static Sender& instance(), static void emitSignal() и QSignal Q_SIGNAL void mySignal() в классе Sender (см. Код ниже). В заголовке класса Qt MyQtClass.h я настроил QSlot Q_SLOT void mySlot(). Я соединяю эти два слота в main.cpp
(const bool connected = QObject::connect(&Sender::instance(), &Sender::mySignal, &w, &MyQtClass::mySlot);)

Через qDebug(); Я обнаружил, что соединение установлено успешно, и как только я вызываю метод emitSignal(), излучается сигнал. Слот, хотя никогда не вызывается.

Я догадываюсь, что моя ошибка в основном при соединении.

Код:

sender.h:

#pragma once
#include <QtWidgets/QMainWindow>
#include <qdebug.h>

class Sender : public QObject
{
    Q_OBJECT
    using QObject::QObject;
public:

    /*----------------------------*/
    /*---Lots of static Members---*/
    /*----------------------------*/


    static Sender& instance(){
        static Sender m_instance;
        return m_instance;
    }

    static void emitSignal() {
        emit instance().mySignal();
    }

    Q_SIGNAL void mySignal() {
        qDebug() << "Signal emitted!";
    }
};

MyQtClass.h

#pragma once
#include <qdebug.h>
#include <QtWidgets/QMainWindow>
#include "ui_MyQtClass.h"

class MyQtClass : public QMainWindow
{
    Q_OBJECT

public:
    MyQtClass(QWidget *parent = Q_NULLPTR);

    Q_SLOT void mySlot() {
        qDebug() << "Slot invoked";
    }

private:
    Ui::MyQtClassClass ui;
};

MyQtClass.cpp

#include "MyQtClass.h"
#include "Sender.h";
#include <qdebug.h>

MyQtClass::MyQtClass(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    qDebug() << "Ui has been setup!";

}

main.cpp

#include "MyQtClass.h"
#include "Sender.h"
#include <qdebug.h>
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyQtClass w;
    w.show();
    const bool connected = QObject::connect(&Sender::instance(), &Sender::mySignal, &w, &MyQtClass::mySlot);
    qDebug() << "Connection established: " << connected;
    Sender::emitSignal();
    return a.exec();
}

Большое спасибо за потраченное время!

1 Ответ

0 голосов
/ 15 января 2019

Я бы проверил вашу систему сборки. Вы не должны иметь возможность компилировать Q_SIGNAL с телом функции без получения ошибки переопределения. Если вы можете построить его, вы, вероятно, не задействуете какой-либо механизм Qt, который вы хотите использовать. У меня нет опыта работы с вашей средой Visual Studio / mingw, но я смог получить следующее для сборки на платформе Linux.

main.cpp

#include <QDebug>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow> 
#include "Sender.h"                                                          
#include "MyQtClass.h"                                                       
//#include "ui_MyQtClass.h"                                                  

MyQtClass::MyQtClass(QWidget *parent)                                        
    : QMainWindow(parent)                                                    
{                                                                            
    qDebug() << "Ui has been setup!";                                        

}                                                                            

int main(int argc, char *argv[])                                             
{                                                                            
    QApplication a(argc, argv);                                              
    MyQtClass w;                                                             
    w.show();                                                                
    const bool connected = QObject::connect(&Sender::instance(), &Sender::mySignal, &w, &MyQtClass::mySlot);
    qDebug() << "Connection established: " << connected;                     
    Sender::emitSignal();
    return a.exec();
} 

sender.h

#pragma once
#include <QtWidgets/QMainWindow>
class Sender : public QObject
{
    Q_OBJECT
    using QObject::QObject;                                                  
public:                                                                      

    /*----------------------------*/                                         
    /*---Lots of static Members---*/                                         
    /*----------------------------*/


    static Sender& instance(){                                               
        static Sender m_instance;                                            
        return m_instance;                                                   
    }

    static void emitSignal() {                                               
        emit instance().mySignal();
    }

    Q_SIGNAL void mySignal();
}; 

MyQtClass.h

#pragma once
#include <QtWidgets/QMainWindow>
#include <QDebug>

class MyQtClass : public QMainWindow
{   
    Q_OBJECT                                                                 

public:
    MyQtClass(QWidget *parent = Q_NULLPTR);                                  

    Q_SLOT void mySlot() {
        qDebug() << "Slot invoked";                                          
    }   

private:
    //Ui::MyQtClassClass ui;
};

Затем я собрал его вручную, вызвав Компилятор мета-объектов

moc Sender.h > moc_Sender.cpp
moc MyQtClass.h > moc_MyQtClass.cpp
g++  main.cpp moc_Sender.cpp moc_MyQtClass.cpp -I /usr/include/x86_64-linux-gnu/qt5/QtCore/ -I /usr/include/x86_64-linux-gnu/qt5 -fPIC -std=c++11 -I /usr/include/x86_64-linux-gnu/qt5/QtWidgets/ -lQt5Core -lQt5Widgets

, который дал ожидаемый результат

user@mintvm ~ $ ./a.out 
Ui has been setup!
Connection established:  true
Slot invoked

Вы пытались использовать систему сборки qmake , чтобы вам не приходилось беспокоиться обо всех деталях, связанных с компиляцией мета-объектной системы?

...