Signal/Slots feature for different classes in Qt C++ - c++

For just one class , i declare a slot and a signal , and in slot method definition i call signal method with emit keyword. But how can i emit signals with one class to another class which has a slot.
Well i try with a button to modify a label text. Button is created by A class (which must emit a signal) , and label is created by class B which must have a slot to modify text on it

It seems like you have class 1, which has a method that will be executed, and will call "emit". When that happens, the slot of another class will find out.
definition of 1st class:
class songs_text {
public:
signals:
void send_signal();
}
int songs_text:function() {
emit send_signal();
}
definition of class 2:
class wind {
public slots:
void continue_job() {
};
}
and your main program:
Wind wind();
Get_source songs_text(&mtempfile);
QObject::connect(&songs_text, SIGNAL(send_signal()),
&wind, SLOT(continue_job()));

Add a public method in the class named void emitSignalBlahBlah() to be a wrapper around the emit code. Then, all the other classes that need to fire this signal will access this object and call the method to do it.

Related

Is it possible to override non-virtual slots in Qt?

I would like to run some of my code when the resizeColumnsToContents slot gets called. However the resizeColumnToContents slot is not virtual. Is there any other way to achieve this?
If the slot was virtual this is what I would like to do:
class DerivedTableView : public QTableView
{
public:
void resizeColumnsToContents()
{
printf("The user wants to resize the columns\n");
QTableView::resizeColumnsToContents();
}
};

c++ QPushButton signal and slot

I have a problem creating a QPushButton and linking its signal to my slots. First, I created a class with the slot:
class A : public QWidget{
public slots:
void handleButton();
};
There is my handleButton function in the .cpp
void A::handleButton(int row, int col){
m_button->setText("Example");
// resize button
m_button->resize(100,100);
}
Then I want to connect the button.
QObject::connect(m_button, SIGNAL(clicked()), qApp, SLOT(handleButton()));
But I got an error when I start the application:
"No such slot"
Make sure that qApp is an object of class A (i.e. where your slot is defined).
That said, the signatures are wrong: a signal links to a slot only if the signature match
http://qt-project.org/doc/qt-4.8/signalsandslots.html
The signals and slots mechanism is type safe: The signature of a signal must match the signature of the receiving slot.
And your slot hasn't the right signature:
http://qt-project.org/doc/qt-4.8/qabstractbutton.html#clicked
void QAbstractButton::clicked ( bool checked = false ) [signal]
You have a few errors in this code, if you define "void handlebutton()" then you must implement void handlebutton() NOT void handlebutton(inx x, int y) this code should not even compile.
More: in QT you CAN ONLY connect SIGNALS and SLOTS with the same parameters so you can connect SIGNAL(clicked()) with SLOT(handlebutton()) but not SIGNAL(clicked() with SLOT(handleButton(int, int)).
Another problem is that connect is executed at runtime so You must compile and run before Qt can show you the error.
So a possible solution is:
define and implement the slot void handlebutton() and connect that to the signal clicked(), then define another method handleButton (int x, int y) that you will call from inside handleButton().
I really hope that makes sense to you.
Your class definition should look like :
class A : public QWidget
{
Q_OBJECT
public slots:
void handleButton(int, int);
};
And you should connect it like:
QObject::connect(m_button, SIGNAL(clicked()),qApp, SLOT(handleButton(int a, int b)));
where a and b are variables for row and column.
This should work. Try understanding basic C++. :)

connecting one signal to multiple slots qt

I am trying to connect two slots with on signal. here is my header file where I have defined my signals
class loginChecker : public QObject
{
Q_OBJECT
public:
static loginChecker *instance(void);
signals:
void loginid();
void loginemail();
private:
loginChecker(void) {}
~loginChecker(void) {}
private:
static loginChecker *s_instance;
};
it is sigalton class. here is my slot which is another signalton class named as loginProcess
the slot name in this class in getUserData(QString& userData)
in The loginChecker.cpp
I am trying to connect these declared signals with getUserData(QString userData) slot
loginProcess *lp;
lp = loginProcess::instance();
here I am accessing instance of loginProcess signalton class which has slot
These are two ways I am trying to connect these signal and slot but none are working
QObject::connect(s_instance, SIGNAL(loginid()), es, SLOT(getUserData(userid)));
this is throwing no such slot error at runtime
`QObject::connect(s_instance, &esCoreAuthenticator::loginid, es, &loginProcess::getUserData(uid));`
this is thworing this error cannot call member function 'void loginProcess::getUserData(const QString&)' without object at compile time
Since your signal has no arguments you can't connect it to slot which has some.
And also it seems to me that in first case you should try SLOT(getUserData(QString&)) and in second case just &loginProcess::getUserData without any parenthesis.

Qt4: connect slot and signal from other forms

I have a small problem. I want run function in MainWindow from AnotherWindow. I can't set connect() for it.
Main class: MainWindow
Other form: AnotherWindow
Function in main class: setVariable(QString)
Function in other form: btnClicked()
I have now connected button signal clicked():
// In AnotherWindow.cpp
connect(ui->btnOK, SIGNAL(clicked()), this, SLOT(btnOkClicked()));
// Function in same file
void interfaceWindow::btnOkClicked() {
/* Some actions - emit signal? */
this->close();
}
btnOkClicked() are declared as private slot.
// In MainWindow.cpp
void MainWindow::setVariable(QString _var) {
this->var = _var;
}
setVariable(QString) are declared as public slot.
How I can send variable from AnotherForm (from btnOkClicked() function) to MainWindow (setVariable(QString) function) ? How and where I must send signal and make connection?
I readed about signals and slots, but my code don't work - I don't paste it here because it's terrible :)
Any help for Qt newbie?
You need to have an reference of AnotherWindow in MainWindow OR vice versa. Then you need the following things:
// AnotherWindow.h
signals:
void buttonOkClickedSignal(QString var);
// AnotherWindow.cpp
void interfaceWindow::btnOkClicked() {
emit buttonOkClickedSignal("The button got clicked!");
this->close();
}
Next step varies based on whether MainWindow has reference to AnotherWindow or vice versa. You can either:
// AnotherWindow.cpp
connect(this, SIGNAL(buttonOkClickedSignal(QString), &mainWindow, SLOT(setVariable(QString)));
or:
// MainWindow.cpp
connect(&anotherWindow, SIGNAL(buttonOkClickedSignal(QString), this, (SLOT(setVariable(QString)));
If you are invoking the slot through signal it shouldn't matter whether it's private or public (see Qt Documentation).
Hope this helps.
I'm not entirely sure I understand your question, but let me try.
You want to be able to fire a slot in another class. There are a few ways you can do that.
Declare one as a friend class to the other. Then they can see the protected and private variables/memebers
It is possible to make slots static so you can call them without a class object.
For example,
class MainWindow {
private slot:
void setVariable(QString);
}
class AnotherWindow {
friend class MainWindow;
MainWindow *window;
public:
AnotherWindow() {
connect(this, SIGNAL(fire(QString)), window, SLOT(setVariable(QString)));
}
signals:
void fire(QString);
public slots:
void onButtonClicked() {
emit fire(QString);
}
}
The previous is pseudocode so don't expect it to compile. I think this is what you want. Basically since your slot is private on MainWindow you need to make it a friend. To connect, it needs to be a member. Then when the onButtonClicked slot is evoked, then it fire()s the setVarialbe() slot.
Here is a simple code for your another window:
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget(QWidget * parent = 0)
{
okBtn = new QPushButton ("I am Ok!");
MyData = "";
connect(okBtn ,SIGNAL(clicked()),this,SLOT(OnOk()));
}
~MyWidget();
private:
QString MyData;
QPushButton * okBtn;
//something that modify string MyData
signals:
void MyDataSignal(QString);
//Internal slot that emits signal with proper data
private slots:
void OnOk()
{
if(MyData!="")
{
emit MyDataSignal(MyData);
}
}
};
Now in MainWindow create an object of MyWidget (suppose myWid)and connect it to slot
connect(myWid, SIGNAL(MyDataSignal(QString)),this,SLOT(OnMyWidOkClicked(QString)));
the signal will pass string to slot.
While making signals and slots keep in mind following points:
To connect a signal to a slot (or to another signal), they must have the same parameter
Parameters should be in the same order in both signal and slot.
if a signal has more parameters than the slot it is connected to, the additional parameters are simply ignored but opposite is not possible.
If you will connect a signal that have unmatched parameters to slot then no compile time error will occur but at run time command window will show a warning that signal/slot/connection does not exist.

Pointer to a slot function

I have some slot function defined in my class which do some actions. I wanted to create a possibility to allow the user of my class to define his own slot function (replacing the function from my class for his own). I tried to achieve it by pointer to a slot function this way:
class asd {
Q_OBJECT
private:
void ( asd::*m_funcTrigger )( QAction* );
public:
asd();
// and some method to pass the pointer
private slots:
void actionTrigger( QAction* );
};
the constructor:
asd::asd() {
// set the slot function from class as default
m_funcTrigger = &asd::actionTrigger;
// m is a QMenu object
connect(m, SIGNAL(triggered(QAction*)), this, SLOT(m_funcTrigger(QAction*)));
}
actionTrigger's implementation is not important I think.
So, when I put actionTrigger into the SLOT() it works ok. When I put there the m_funcTrigger it doesn't - nothing happens (the slot is not found by the Qt). I was sure that it is beacuse the pointer is not in the slots section in the class, so I just put it there:
private slots:
void ( asd::*m_funcTrigger )( QAction* );
void actionTrigger( QAction* );
but I got strange error:
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(151,5): error MSB6006: "cmd.exe" exited with code 1.
I completely don't know how to deal with this.
EDIT:
I think the reason why it's not found by the Qt:
From what I have read over the Internet, the SLOT() just returns a simple const char* which includes identifier name of the method passed to the SLOT, Therefore the Qt completely doesn't know what the pointer is pointing at. It just looks after the m_funcTrigger( QAction* ) function.
I created another solution (which works I will put it here later I'm currently at work) that requires the user of the class to pass a SLOT(hisOwnFunction()) into the function which sets the slot function. Because the class uses signal-slots idea, so it's Qt dependent and I think because of that it's ok to pass SLOT there instead of a pointer. What do you think?
You can make your slot virtual, so derived class can override it.
You can call m_funcTrigger in your slot by yourself:
private slots:
void actionTrigger_slot( QAction* a)
{
m_funcTrigger(a);
}