0

I have difficulty connecting to SLOTs defined in a different class. I have 2 classes - Computations and MainWindow. MainWindow is supposed to handle the GUI part of the program only and Computations handles the calculations. I am creating a calculator.

Basically, I want to understand how I can connect to SLOTs in the Computations Class from the MainWindow Class.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Elmon
  • 9
  • 2

4 Answers4

7

I guess you already checked the Qt Signals & Slots page. To implement what you want you need to have an instance of your class in the other one.

So for example in your MainWindow class, you can include the Computations class and create a member variable of it:

#include "computations.h"

class MainWindow : public QMainWindow
{
   Q_ObBJECT
public:
   //..
private:
   Computations *_computation;
};

and then in the constructor of MainWindow after initializing the _computation object (_computation = new Computations();) you do the connections like this (works for Qt5):

QObject::connect(_computation, &Computations::somethingHappened, this, &MainWindow::doSomeGuiStuff);
QObject::connect(this, &MainWindow::guiThingHappened, _computation, &Computations::doSomeComputation);

depending on which way it should go.

I hope this helps.

Mariam
  • 342
  • 3
  • 18
1

This is another version how to use, I think can be easier to understand for beginners

You need define signal and slots in your classes. Add to header of your class, for example signals to MainWindow, slots to Computations

public slots:
    void something();

signals:
    void something_happend();

Then, in anywhere, where you want use it, in your example in mainwindow.cpp, you need to connect signal and slot. Do this by QObject::connect :

QObject::connect(who_emit,SIGNAL(what_signal),who_receive,SLOT(what_slot))

Example:

mainwindow.h

signals:
    void something_happend();

computations.h

public slots:
    void something_happend();

mainwindow.cpp

Computations *c = new Computations(this);
QObject::connect(this,SIGNAL(something_happend()),c,SLOT(something()));

If you want to pass some arguments, SIGNAL and SLOT that you want to connect need have same types of arguments:

public slots:
    void something(int c);

signals:
    void something_happend(int c);

QObject::connect(this,SIGNAL(something_happend(int)),c,SLOT(something(int)));
pomi11
  • 46
  • 4
0

Such connections belong at a level where both the UI and the controller (computation object) are available. Thus, either in the body of main, or in a class that composes that various elements of the application at a high level (such a class usually shouldn't derive from QApplication, though).

It is almost always too tight of a coupling if the UI class knows of the existence of the computation object, or is somehow tied to its details. I usually design the UI to have an interface composed of signals and slots of as generic a nature as practicable, and then tie it to one or more controller objects via signal/slot connections. I also leverage the property system to expose UI-relevant properties in a generic manner, often using viewmodel objects to interface a UI-agnostic controller to a concrete kind of a UI.

In your case, I'd suggest that neither MainWindow know of Computations, nor vice versa:

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);
  Computations comp;
  MainWindow ui;
  QObject::connect(&comp, ..., &ui, ...);
  /* more connections here */
  ui.show();
  return app.exec();
}

For more concrete examples, see answer #1 or answer #2.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
0

you need slots and signals because those work together, like this: your file.h

public slots:
    void start();

signals:
    void levelChanged(int level);

implementing:

void MainBoard::start()
{
    isStarted = true;
    clearBoard();
    emit levelChanged(1);

}

now you need to link a button

startButton = new QPushButton(tr("&Start"));
startButton->setFocusPolicy(Qt::NoFocus);

connect(startButton, &QPushButton::clicked, board, &MainBoard::start);