PDA

View Full Version : Separate Slot Connection in another File



superpomax
29th June 2018, 14:18
I made a big dialog window using designer. Can I separate the slots and connections of the windows in another file. I got stuck at the function
QObject::connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(quit()) ) where the third argument give an error.
I also tried to give a QWidget* to the main window but it doesn't work either.

Lesiok
29th June 2018, 14:55
The signal and slot must have the same argument. You can not connect the signal with the argument to the slot with no arguments.

Ginsengelf
2nd July 2018, 07:25
@Lesiok
I don't think that's true. You can have less arguments in the slot than in the signal. The other way round is impossible.

@superpomax:
"gives an error" is not helpful. What error?

Ginsengelf

superpomax
3rd July 2018, 19:43
At first, I went general because it is a big project. Here's the code, I've tried to clean it to only keep the function necessary.
Also, I wrote some of the code in french, I don't think it is necessary to get what everything means, but I can translate if you need me to.

On line 10 and 11 of connexion.cpp, I get this error : path\Connexion.cpp:10: error: no matching function for call to 'QObject::connect(QPushButton*&, const char*, Ui::Dialog*&, const char*)'
QObject::connect(ui->pushButtonChoisirFichierOrigine,SIGNAL(clicked(boo l)),ui,SLOT(definePathFichierOrigine()));

Dialog.h


#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include "ui_dialog.h"

#include "Connexion.h"

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
Q_OBJECT

public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
void createConnexion();
public slots:
void definePathExeConsole();
void definePathFichierOrigine();
public:
Ui::Dialog *ui;

Dialog.cpp


#include "Dialog.h"

Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);

createConnexion();
}

void Dialog::createConnexion()
{
Connexion connecter(ui);
connecter.connexionSignauxSlots();
}

void Dialog::definePathFichierOrigine()
{
ui->labelChoisirFichierOrigine->setText(QFileDialog::getExistingDirectory(this));
}

void Dialog::definePathExeConsole()
{
ui->labelChoisirExeConsole->setText(QFileDialog::getOpenFileName(this, "Ouvrir un fichier", QString(), "Exécutable (*.exe)"));
}



Connexion.h

#ifndef CONNEXION_H
#define CONNEXION_H

#include "Dialog.h"

class Connexion
{
public:
Connexion(Ui::Dialog *dialog){ui = dialog; }
void connexionSignauxSlots();
private:
void connexionSimulation();
private:
Ui::Dialog *ui;
};

#endif // CONNEXION_H



Connexion.cpp

#include "Connexion.h"

void Connexion::connexionSignauxSlots()
{
connexionSimulation();
}

void Connexion::connexionSimulation()
{
QObject::connect(ui->pushButtonChoisirFichierOrigine,SIGNAL(clicked(boo l)),ui,SLOT(definePathFichierOrigine()));
QObject::connect(ui->pushButtonChoisirExeConsole,SIGNAL(clicked(bool)), this,SLOT(definePathExeConsole()));

d_stranz
3rd July 2018, 23:11
QObject::connect(ui->pushButtonChoisirFichierOrigine,SIGNAL(clicked(boo l)),ui,SLOT(definePathFichierOrigine()));


In this line, definePathFichierOrigine() is a member function (slot) of the Dialog class, not the Ui:: Dialog class, so that's an error.



QObject::connect(ui->pushButtonChoisirExeConsole,SIGNAL(clicked(bool)), this,SLOT(definePathExeConsole()));


In this line, "this" is an instance of the Connexion class. Not only does it not have a slot named definePathExeConsole(), it isn't derived from QObject at all so it can't have slots.

Even if you do manage to get pointers to the right class in that function, in my opinion it's a really bad design. You have two classes that must know the intimate details of your GUI - Dialog (so it can create it), and Connexion (so it can do nothing more than connect the signals and slots).

The whole idea of good C++ design is to encapsulate the details inside a single class so other code that uses that class can simply use the methods of that class and not have to care about how those methods work. Your design makes that impossible - Connexion -must- know about every detail of Ui:: Dialog, right down to the names you choose for the ui widgets, and if you change anything about the UI, you have to at least change Connexion and probably Dialog as well, and rebuild them both.

It is a guaranteed way to introduce bugs into your code that take a long time to track down.

superpomax
4th July 2018, 14:18
For the first one, I declared Dialog a member of the namespace Ui ( line 9 to 11). Why Ui::Dialog and Dialog aren't the same ?
With your explanation I get why the second line won't work.

I also get the same error when I try to run my program using Dialog instead of Ui::Dialog.
Finally, my dialog.cpp file is already at 715 line of code, so I wanted to separate the connections in another file.

EDIT : I removed Ui and I get class 'Dialog' has no member named 'pushButtonFichierOrigine'. I added another private attribute which Dialog which I give to the constructor of Connexion.
I can connect signal to slot with a line of code similar to this


QObject::connect(window->comboBoxChampForceMOFH2,SIGNAL(currentIndexChanged (int)),ui,SLOT(champForceMOFIdentique()));

where ui is an instance of Dialog and window is an instance of Ui::Dialog although I don't feel like this is the correct solution t to make the code more modular.

superpomax
4th July 2018, 20:20
Here's the constructor of Connexion to make it clearer

class Connexion
{
public:
Connexion(Dialog *dia,Ui::Dialog *win){ui = dia; window = win; }
private:
void connexionSimulation();

private:
Dialog *ui;
Ui::Dialog *window;
};

d_stranz
5th July 2018, 21:37
Why Ui:: Dialog and Dialog aren't the same ?

Ui:: Dialog is a class named "Dialog" that is created in the "Ui" namespace when your Dialog.ui file is processed by Qt's uic compiler as part of the build procedure. You will see it in your GeneratedFiles folder. "Dialog" is a different class; it is the one you have written that uses the widgets defined as variables in the Ui:: Dialog class.