PDA

View Full Version : Custom signals to slot in a different class.



sisco
11th April 2011, 13:40
ok so i have a small problem with the code im trying to run and since i am still a noob with Qt and c++ i think i need some help.

ok so, i have a form that i designed with Qt designer with a few buttons on it, now when i click the button i want it to emit a custom signal wich works fine. now here is where i got lost. i have a class with an empty window where i want to catch that signal. the problem is i cant seem to get it to work. what do i need to do to get this to work?

here are the .h files:

buttons.h

#ifndef BUTTONFORM_H
#define BUTTONFORM_H

#include <QWidget>

namespace Ui {
class buttonForm;
}

class buttonForm : public QWidget
{
Q_OBJECT

public:
explicit buttonForm(QWidget *parent = 0);
~buttonForm();
signals:
void saveClicked();
void openClicked();
void resetClicked();
void sendClicked();

private:
Ui::buttonForm *ui;

private slots:
void save();
void open();
void reset();
void send();
};

#endif // BUTTONFORM_H

customclass.h

#ifndef CONFIGDIALOG_H
#define CONFIGDIALOG_H

#include <QObject>
#include <QWidget>

class configDialog : public QObject
{
//Q_OBJECT

public:
configDialog();

private:
QWidget *form;

private slots:
void saveConfig();
};

#endif // CONFIGDIALOG_H
as you can maybe see i am trying to connect the signal saveClicked of buttons.h to the slot saveConfig from customclass.h am i trying completely the wrong thing here or should i be abdle to get it to work and how?

BalaQT
11th April 2011, 14:25
hi,

i want it to emit a custom signal wich works fine
1)on seeing your code, why you need custom signal? since you already have clicked() signal?


i am trying to connect the signal saveClicked of buttons.h to the slot saveConfig from customclass.h
2)how both classes are related? private slots limit your slot's visibility.
anyway, just try,

connect(yourButtonObject,SIGNAL(yourSignal),yourCo nfDialog,SLOT(saveConfig()));

hope it helps
bala

sisco
11th April 2011, 15:16
1)on seeing your code, why you need custom signal? since you already have clicked() signal?

This is done because from my custom class i cant reach the default signals from the buttonform?


2)how both classes are related? private slots limit your slot's visibility.
anyway, just try,

connect(yourButtonObject,SIGNAL(yourSignal),yourCo nfDialog,SLOT(saveConfig()));

the constructor from my custom class:

configDialog::configDialog()
{
form = new QWidget();
buttonForm *button = new buttonForm(form);
connect(button, SIGNAL(saveClicked()),this, SLOT(saveConfig())); //try to connect signal from button to custom slot.

form->setWindowIcon(QIcon(":/icons/Gear-01.png"));
form->setWindowTitle("Simulator Settings");
form->show();
}
as you can see i am trying to connect the signal the way you described but this is giving me these errors:


./debug/configdialog.o: In function `configDialog':
C:\Users\sisco\Dropbox\Documents\School\Project 4\gebruikers_interface\Project4_Gebruikers_interfa ce/configdialog.cpp:11: undefined reference to `vtable for configDialog'
C:\Users\sisco\Dropbox\Documents\School\Project 4\gebruikers_interface\Project4_Gebruikers_interfa ce/configdialog.cpp:11: undefined reference to `vtable for configDialog'
./debug/mainwindow.o:mainwindow.cpp:(.text$_ZN12configDial ogD1Ev[configDialog::~configDialog()]+0xb): undefined reference to `vtable for configDialog'
collect2: ld returned 1 exit status

according to this (http://www.digitalfanatics.org/projects/qt_tutorial/chapter02.html) that should work right?

Thanks,

Sisco

EDIT:
Got rid of the errors and the project builds now, one problem the signal emits but the slot does not do anything :confused:

viulskiez
11th April 2011, 17:30
one problem the signal emits but the slot does not do anything
Do you connect your signals slots like this?


// your button form constructor (FORWARD clicked signal)
connect(saveButton, SIGNAL(clicked()), this, SIGNAL(saveClicked()));

// custom class constructor
connect(button, SIGNAL(saveClicked()), this, SLOT(saveConfig()));

sisco
11th April 2011, 17:34
Do you connect your signals slots like this?


// your button form constructor (FORWARD clicked signal)
connect(saveButton, SIGNAL(clicked()), this, SIGNAL(saveClicked()));

// custom class constructor
connect(button, SIGNAL(saveClicked()), this, SLOT(saveConfig()));


something like that yes:

buttonform:

connect(ui->saveButton, SIGNAL(clicked()), this, SLOT(save()));
void buttonForm::save()
{
emit saveClicked(); //when debugging breakpoint stops here so the signal is emitted.
}

custom form:

connect(button, SIGNAL(saveClicked()),this, SLOT(saveConfig()));
void configDialog::saveConfig()
{
QMessageBox box;
box.setText("Save clicked!"); //nothing happens here, debugging doesnt even stop at breakpoint.
box.exec();
}

i also tried your example but this gives me the same problem.

viulskiez
11th April 2011, 17:52
connect(ui->saveButton, SIGNAL(clicked()), this, SLOT(save())); // SIGNAL -> SLOT

So you only connect the signal to the slot. You do not forward the signal to the form signal.

connect(ui->saveButton, SIGNAL(clicked()), this, SIGNAL(saveClicked())); // SIGNAL -> SIGNAL

sisco
11th April 2011, 17:58
yes, i connect the clicked() signal to the slot called save() and from within that slot i emit the saveclicked() signal.

connect(ui->saveButton, SIGNAL(clicked()), this, SLOT(save()));
void buttonForm::save()
{
emit saveClicked(); //when debugging breakpoint stops here so the signal is emitted.
}

wich should have the same effect as what you are suggesting. wich also doesnt work for me btw. :(

viulskiez
11th April 2011, 18:00
still doesn't solve your problem?

sisco
11th April 2011, 18:15
as i said before both options dont do anything.
i'l place all of the code that has anything to do with those 2 classes. maybe someone can see what the problem is.



//buttonform.h
#ifndef BUTTONFORM_H
#define BUTTONFORM_H

#include <QWidget>

namespace Ui {
class buttonForm;
}

class buttonForm : public QWidget
{
Q_OBJECT

public:
explicit buttonForm(QWidget *parent = 0);
~buttonForm();

signals:
void saveClicked(void);
void openClicked(void);
void resetClicked(void);
void sendClicked(void);

private:
Ui::buttonForm *ui;

private slots:
void save();
void open();
void reset();
void send();
};

#endif // BUTTONFORM_H



//buttonform.cpp
#include "buttonform.h"
#include "ui_buttonform.h"

buttonForm::buttonForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::buttonForm)
{
ui->setupUi(this);
connect(ui->saveButton, SIGNAL(clicked()), this, SLOT(save()));
}

buttonForm::~buttonForm()
{
delete ui;
}

void buttonForm::save()
{
emit this->saveClicked();
}



//configdialog.h
#ifndef CONFIGDIALOG_H
#define CONFIGDIALOG_H

#include <QObject>
#include <QWidget>

class configDialog : public QObject
{
Q_OBJECT

public:
configDialog();

private:
QWidget *form;

public slots:
void saveConfig();
};

#endif // CONFIGDIALOG_H



//configdialog.cpp
#include <connectform.h>
#include <freezeform.h>
#include <enginecheckform.h>
#include <buttonform.h>

configDialog::configDialog()
{
form = new QWidget();
spinBoxForm *spinbox = new spinBoxForm(form);
dtcForm *dtc = new dtcForm(form);
freezeForm *freeze = new freezeForm(form);
engineCheckForm *check = new engineCheckForm(form);
connectForm *connectf = new connectForm(form);
buttonForm *button = new buttonForm(form);

dtc->setGeometry(10,10,dtc->width(),dtc->height());
spinbox->setGeometry(dtc->width()+10,10, spinbox->width(),spinbox->height());
freeze->setGeometry(10,dtc->height()+10,freeze->width(),freeze->height());
check->setGeometry(freeze->width()+10,dtc->height()+10,check->width(),check->height());
connectf->setGeometry((freeze->width()+check->width()+10),dtc->height()+10,connectf->width(),connectf->height());

form->setFixedSize((dtc->width() + spinbox->width()+10),(dtc->height() + check->height()+10));

button->setGeometry((freeze->width()+check->width() + connectf->width()+10), dtc->height()+15,form->width()-freeze->width()-check->width()-connectf->width() -10,(form->height()-dtc->height()-10));
connect(button, SIGNAL(saveClicked()),this, SLOT(saveConfig()));

form->setWindowIcon(QIcon(":/icons/Gear-01.png"));
form->setWindowTitle("Simulator Settings");
form->show();
}

void configDialog::saveConfig()
{
QMessageBox box;
box.setText("Save clicked!");
box.exec();
}

viulskiez
11th April 2011, 18:20
From customclass.h


#ifndef CONFIGDIALOG_H
#define CONFIGDIALOG_H

#include <QObject>
#include <QWidget>

class configDialog : public QObject
{
//Q_OBJECT

public:
configDialog();

private:
QWidget *form;

private slots:
void saveConfig();
};

#endif // CONFIGDIALOG_H


Do you leave Q_OBJECT macro commented?

sisco
11th April 2011, 18:21
please look above i have the entire code posted. the Q_OBJECT macro is uncommented.

viulskiez
11th April 2011, 18:54
In my opinion, there are nothing wrong with signals / slots connections. Just try to delete the files in your build directories and then rebuild your project. Hope another member can helps..

sisco
11th April 2011, 19:09
lets hope, this is really getting on my nerves and i have no idea what's wrong! :(
i already tried everything i could think of, rebuild the project so many times and nothing helps!