PDA

View Full Version : Custom signal and slots



amitahire
27th June 2012, 11:07
Hello again,


I am trying to make a simple application where when I click a button the count is displayed in the QLineEdit. But I cant get the signal going. I have read different documentations but for custom signal and slots everywhere I see I get a different account or method.

I am posting my files. Please help me understand the concept

click.h

#ifndef CLICK_H
#define CLICK_H

#include<QMainWindow>
#include<QLineEdit>
#include<QPushButton>

namespace Ui
{
class click_me;
}


class click_me:public QMainWindow
{
Q_OBJECT
public:
click_me(QWidget *Parent=0);
signals:
void click1(int);
private slots:
void disp();
private:
Ui::click_me *ui;
private:
QPushButton *p1;
QLineEdit *l1;
};
#endif


click.cpp

#include"click.h"
#include"ui_click.h"

int count=0;

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

//int count=0;
connect(ui->p1,SIGNAL(click1(int)),ui->l1,SLOT(disp(int)));
}

void click_me::disp(int)
{

//emit click1(count);
count = count +1;

QString s=QString::number(count);


ui->l1->setText(s);
}

//int click_me::click1(int co)
//{
//
// emit click1();
//return co;

//}
7906

I am just unable to understand how do I pass parameters in the signal and even if I am passing one.... How do I go about declaring, defining and passing them.

Clearing its a off day for me :-\

code_err
27th June 2012, 11:43
This is completely wrong. You didn't get the idea of signals and slots. What you've done is:
- you created signal and slot for class click_me not for QLineEdit and QPushButton so you cannot connect them as SIG & SLOT for instances of those classes
This is wrong:
connect(ui->p1,SIGNAL(click1(int)),ui->l1,SLOT(disp(int)));

I know what you want to do
You wanna click the button and invoke slot which put value into QLineEdit. You can do it this way:
- use one of Qt's original signals for QPushButton - clicked() and connect to your own slot disp(). clicked() doesn't get any value so if you wanna have signal with value you will have to create new class for button derived from QPushButton but i think that it isn't necessary in this case.

It has to look like that:
connect(ui->p1, SIGNAL(clicked()), this, SLOT(disp()));

You don't need any value passed to signal because you don't used it in disp() method. QPushButton's signal is invoked automatically by QPushButton when you click on instance of this class or derived class.

And your own signals are invoked by using: emit name_of_signal();

amitahire
27th June 2012, 11:54
So in order to pass parameter in my custom signal I need to create a new class from QPushButton.

Well you have got exactly what I am trying to achieve. But I am still confused as to if I dont pass any value to disp() how is it gonna setText in the LineEdit?? Sorry still confused.


This is completely wrong. You didn't get the idea of signals and slots. What you've done is:
- you created signal and slot for class click_me not for QLineEdit and QPushButton so you cannot connect them as SIG & SLOT for instances of those classes
This is wrong:
connect(ui->p1,SIGNAL(click1(int)),ui->l1,SLOT(disp(int)));

I know what you want to do
You wanna click the button and invoke slot which put value into QLineEdit. You can do it this way:
- use one of Qt's original signals for QPushButton - clicked() and connect to your own slot disp(). clicked() doesn't get any value so if you wanna have signal with value you will have to create new class for button derived from QPushButton but i think that it isn't necessary in this case.

It has to look like that:
connect(ui->p1, SIGNAL(clicked()), this, SLOT(disp()));

You don't need any value passed to signal because you don't used it in disp() method. QPushButton's signal is invoked automatically by QPushButton when you click on instance of this class or derived class.

And your own signals are invoked by using: emit name_of_signal();

sonulohani
27th June 2012, 12:14
Why you're declaring pushbutton and lineEdit in header file if you're dragging it into your ui file. Directly use it. Here is the code see this:------>



#ifndef CLICK_H
#define CLICK_H

#include<QMainWindow>
#include<QLineEdit>
#include<QPushButton>

namespace Ui
{
class click_me;
}


class click_me:public QMainWindow
{
Q_OBJECT
public:
click_me(QWidget *Parent=0);
private slots:
void disp();
private:
Ui::click_me *ui;
int count;
};
#endif




#include"click.h"
#include"ui_click.h"


click_me::click_me(QWidget *parent):QMainWindow(parent),ui(new Ui::click_me)
{

count=0;
ui->setupUi(this);

//int count=0;
connect(ui->p1,SIGNAL(clicked()),this,SLOT(disp()));
}

void click_me::disp()
{

//emit click1(count);
count = count +1;

QString s=QString::number(count);


ui->l1->setText(s);
}


Read Documentation properly.

If you're declaring it in the class then why you've to pass. Just directly use it. Clear some C++ concept.

code_err
27th June 2012, 12:22
Well you have got exactly what I am trying to achieve. But I am still confused as to if I dont pass any value to disp() how is it gonna setText in the LineEdit?? Sorry still confused.I see, you have problems with basic c++, variable count has to be declared before you can use it so you have to add this variable to your class definition and initialize it in constructor. Then method disp() should work.

And also this:
void click_me::disp(int)
In declaration there was no int argument, and even if it was you always have to give name to passed value in definition of method.

sonulohani
27th June 2012, 12:28
hey, that i have declared count in the header file. Why dont you see that?????

code_err
27th June 2012, 13:45
Sorry, you made count global variable (but it's not declaration in header), didn't see it before.

amitahire
2nd July 2012, 08:40
Hello again,


I am trying to make a simple application where when I click a button the count is displayed in the QLineEdit. But I cant get the signal going. I have read different documentations but for custom signal and slots everywhere I see I get a different account or method.

I am posting my files. Please help me understand the concept

click.h

#ifndef CLICK_H
#define CLICK_H

#include<QMainWindow>
#include<QLineEdit>
#include<QPushButton>

namespace Ui
{
class click_me;
}


class click_me:public QMainWindow
{
Q_OBJECT
public:
click_me(QWidget *Parent=0);
signals:
void click1(int);
private slots:
void disp();
private:
Ui::click_me *ui;
private:
QPushButton *p1;
QLineEdit *l1;
};
#endif


click.cpp

#include"click.h"
#include"ui_click.h"

int count=0;

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

//int count=0;
connect(ui->p1,SIGNAL(click1(int)),ui->l1,SLOT(disp(int)));
}

void click_me::disp(int)
{

//emit click1(count);
count = count +1;

QString s=QString::number(count);


ui->l1->setText(s);
}

//int click_me::click1(int co)
//{
//
// emit click1();
//return co;

//}
7906

I am just unable to understand how do I pass parameters in the signal and even if I am passing one.... How do I go about declaring, defining and passing them.

Clearing its a off day for me :-\

Hello guys -- thanks for your reply but I think you didnt get what I was asking for and also my code last time was horrible.

Now check this is out

click_init.cpp


#include<QtGui>
#include"click.h"

int main(int argc,char *argv[])
{
QApplication a(argc,argv);
click_me w;
w.show();
return a.exec();
}

click.h

#ifndef CLICK_H
#define CLICK_H



#include<QMainWindow>
#include<QLineEdit>
#include<QPushButton>

namespace Ui
{
class click_me;
}


class click_me:public QMainWindow
{
Q_OBJECT
public:
click_me(QWidget *parent=0);
//{ count = 0; }

int value() const { return count;}
signals:
void click1(int val);
private slots:
void disp(int val);
private:
Ui::click_me *ui;
private:
//QPushButton *p1;
//QLineEdit *l1;
int count;

};

#endif // CLICK_H

click.cpp


#include"click.h"
#include"ui_click.h"

//int count=0;

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

count=0;
connect(this,SIGNAL(click1(int)),this,SLOT(disp(in t)));
ui->l1->setText("0");

}

void click_me::disp(int val)
{
//if (val != count) {
count = val+1;
QString s=QString::number(count);
ui->l1->setText(s);
emit click1(count);
//}

}


Now this works in the Creatoe but the slots just doesnt work. I am trying to increment and keep the updated value in textbox.

Please can you check whether the signal and slots are defined properly?
And whether my logic is correct, if not please explain it to me. Thanks

Lesiok
2nd July 2012, 08:44
But this is "never ending loop". In slot disp You emit signal click1 which is connected to slot disp which is emit......

amitahire
2nd July 2012, 08:50
So where do I emit click1? Some signal of QPushButton? like click() or something?

EDIT - I can call QPushButton::click() and call emit from there but it gives me error saying " mulltiple definition" and ofcourse I cannot connect click() and disp(int) because of the parameter mismatch. So how do I go about it?

sonulohani
2nd July 2012, 09:01
Hey amitahire,

why you are creating signal click1(int) as there is already an inbuilt signal in qt.
remove click1(int val) signal from header file and in connect() method write this,
connect(ui->p1,SIGNAL(clicked()),this,SLOT(disp())); see my code.
why you want to send the argument if you already get it without sending it.
And also, if you want to emit your own signal then create your own class inheriting QPushButton class and there emit your signal.

amitahire
2nd July 2012, 09:14
Ok if I dont go passing around arguments in my signal and slots.How do I go about updating the count variable?

And in order to emit my own signal - I need to create my own class inherting QPushButton. Thanks for this.

Added after 5 minutes:


Hey amitahire,

why you are creating signal click1(int) as there is already an inbuilt signal in qt.
remove click1(int val) signal from header file and in connect() method write this,
connect(ui->p1,SIGNAL(clicked()),this,SLOT(disp())); see my code.
why you want to send the argument if you already get it without sending it.
And also, if you want to emit your own signal then create your own class inheriting QPushButton class and there emit your signal.

You think this will work?? Its not. Any suggestions?

#include"click.h"
#include"ui_click.h"

//int count=0;

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

count=0;
connect(this,SIGNAL(click()),this,SLOT(disp()));
ui->l1->setText("0");

}

void click_me::disp()
{
//if (val != count) {
count = count +1;

QString s=QString::number(count);
ui->l1->setText(s);
//emit click1(count);
//}

}

sonulohani
4th July 2012, 10:59
hey, what are you trying to do??? Please specify.... What output at last do you want???? I will show you.....

high_flyer
4th July 2012, 11:23
@amitahire

I am just unable to understand how do I pass parameters in the signal and even if I am passing one.... How do I go about declaring, defining and passing them.

Your problem is not a Qt problem, but understanding of what a function call is.
We can't help you with that - you will have to learn C++ first.

There is no need to use signal and slot inside the same object - it CAN be done, but why do it?
When you connect a signal to a slot, you are performing a call back.
This makes sense mostly in cases where the caller doesn't know about the called object.
But when you are in your own class, you can just directly call your slot:

void click_me::disp()
{
//if (val != count) {
count = count +1;

QString s=QString::number(count);
ui->l1->setText(s);
//emit click1(count); //this will call your slot, so why emit a signal if you can just do:
disp();
//}

}

Leave Qt for now, its too much to take on when you are not yet familiar with C/C++ and general programming concepts.
Start with the basics, once you know them, Qt will make much more sense to you.

sonulohani
4th July 2012, 12:35
Dont leave it, but you've to clear some of your concept in Qt.