0
votes

I'm currently working on a project that need the connection between a QPushButton of a Qwidget class (window) and a void method from a "classical" class.

I've tried to connect them with all the solution that I've read but none works correctly.
Either the compiler returns me

QObject::connect: No such slot QWidget::Class::metoh()

or it won't compile at all without errors.

Here's the simpliest code that I've tried. I read the Qt documentation but it didn't help me. I've also tried to include the Q_OBJECT Macro but it lead to errors. I've also read that with Qt5 it's no more mandatory to define slots. Have I understood correctly ?
How can I connect the Some_Class method to the QPushButton ?

 // Classical class header //   
#ifndef DEF_CLASS
#define DEF_CLASS

#include <iostream>
#include <cstdlib>
#include <string>


class Some_class
{
    protected: // permet l'acces pour les methodes style soin

    Some attributes;

    public:
    Some_Class(int id);
    //Personnage(int id, int vieAtStart, int degatsArmeAtStart);

    void method();

    // obligation de passer par des references pour avoir une modification effective 

    ~Some_Class();
};

#endif

// Classical class cpp //

#include "Some_Class.h"

#include <QObject>

#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
using namespace std;

    Some_Class::Some_Class(int id)
    {
        Id = id;
        some attributes;
    };

    void Some_Class::method()
    {
        modification of attributes;
    };

// Window class header //

#ifndef DEF_WINDOW
#define DEF_WINDOW

#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QIcon>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QImage>
#include <QPixmap>
#include <QLabel>
#include <QGraphicsPixmapItem>
#include "Some_Class.h"


class Window : public QWidget // On hérite de QWidget (IMPORTANT)
{
    public:
    Window(Some_Class test);

    // public slots:
    // void go_right();

    private:

    QPushButton *m_button; 
};

#endif

// Window class cpp //

#include "Window.h"

#include <string>
#include <QObject>

Window::Window(Some_Class test) : QWidget()
{
    setFixedSize(874, 968);

    m_button = new QPushButton("test", this);

    QObject::connect(m_button, SIGNAL(clicked()), this, SLOT(Some_Class::method()));
    //QObject::connect(m_bouton_droite, SIGNAL(clicked()), qApp, Personnage::go_right());
    //QObject::connect(m_bouton_droite, &QPushButton::clicked,qApp, Personnage::go_right());
}

#include <QApplication>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLabel>
#include <QIcon>
#include "Window.h"
#include "Some_Class.h"
#include <QObject>

// main.cpp //

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    Window win(Heros);
    win.show();

    return app.exec();
}
1

1 Answers

4
votes

First, you will need an object of Some_Class with an appropriate scope. Currently you only have test in your constructor which is a value parameter and thus gets destroyed when the constructor returns. One option would be to pass in test as a pointer if the object you are passing in has the correct lifetime.

Window::Window(Some_Class *test)

If that is not appropriate in your case you will need to keep a copy inside your Window object. For the rest of this answer I will however assume you pass in a pointer.

With a normal C++ object (not a QObject) you cannot use the SIGNAL/SLOT macro's because they require the use of the slot/signal markers in the class definition. I see you tried to use the modern method pointer syntax but you made one error. The third parameter needs to be the address of an object of type Some_Class.

QObject::connect(m_button, &QPushButton::clicked, test, &Some_Class::method);

However that is not all, for this to work the signature of clicked has to match with Some_Class::method which it doesn't. clicked has a bool checked parameter. The construct with the SIGNAL/SLOT macro's allows the slot to have less parameters but this version of connect is more strict and requires a strict match. You can either add the parameter to method or use a lambda if you have C++11.

QObject::connect(m_button, &QPushButton::clicked, [test] (bool) {
         test->method();
     });