Solved Calling a Function when a Signal is Emitted from Another Class
-
Hello,
I have two ui in different classes.
In classA ui file has; comboBox and StackedWicked with there pages, and
In classB ui file has; pushButton and textEdit.
When I release pushButton in classB, I would like to add the text in textEdit into comboBox which is stated classA.
And I would like to also change the currentIndex of the stackedWidget in classA.So, there are two changes I would like to do in first class when I release the button. Therefore, I connected a signal my pushButton.released() and a slot which emits.
ClassB.cpp
Second::Second(QWidget *parent) : QWidget(parent), ui(new Ui::Second) { ui->setupUi(this); connect(ui->pushButton, SIGNAL(released()), this, SLOT(emitthesignal())); } void Second::emitthesignal() { emit; }
I have tried related solutions found on the previous topics but I could not make it work.
Any suggestion appriciated. Thank you!
-
@qtross said in Calling a Function when a Signal is Emitted from Another Class:
void Second::emitthesignal() { emit; // it looks you're not emitting anything... }
Take a look at Signals & Slots introduction to check how to define the signal and its arguments (in your case, you'll be emitting the value of the textEdit from class B)
-
@Pablo-J-Rogina thank you for your reply.
It is little bit confusing topic, but I have achieved this. However, i did not get any error but it didt work.in second.h
#include "MainWindow.h" #include "ui_MainWindow.h" public: MainWindow *main; signals: textForCombo(QString try);
in second.cpp
void Second::emitsignal(const QString &arg1) { arg1=ui->textEdit->toPlainText(); emit textForCombo(arg1); connect(this, SIGNAL(textForCombo(QString)),main, SIGNAL(TextReceive(QString))); }
MainWindow.h:
signals: TextReceive(QString try2); private slots: void forstdchange(const QString str);
And in MainWindow.cpp:
{ ui->setupUi(this); connect(this , SIGNAL(TextReceive(QString)),this, SLOT(forstdchange(QString))); } void MainWindow::forstdchange(const QString str) { std::string forstd=str.toStdString(); ui->comboBox->addItem(forstd.c_str()); }
-
I'll just add some comments to help you understand your own code:
void Second::emitsignal(const QString &arg1) { arg1=ui->textEdit->toPlainText(); // How can that work? arg1 is const emit textForCombo(arg1); connect(this, SIGNAL(textForCombo(QString)),main, SIGNAL(TextReceive(QString))); // what is that for? // Note that you add an connection everytime the emitsignal function is run, which is NOT what you want // Also, you already emit in the line above, so you *don't* need this connect here }
void MainWindow::forstdchange(const QString str) // Change to 'const QString &str' { std::string forstd=str.toStdString(); // That looks overly complicated ui->comboBox->addItem(forstd.c_str()); // and creates subtile errors with non-ASCII chars ui->comboBox->addItem(str); // That is much easier }
Regards
-
@aha_1980 Thank you for your reply.
connect(this, SIGNAL(textForCombo(QString)),main, SIGNAL(TextReceive(QString)));
Why I have added this line is I though I need to declare again for accessing first class.ui
with the SIGNAL(TextReceieve(QString)). Therefore, I created void textForCombo.I did not know I can add directly QString as item into comboBox. I thought I needed to convert it to first std::string then to char.
Now, I did changes you suggested and added this line to mainwindow.cpp,
connect(this, SIGNAL(emitsignal(QString)), this, SLOT(forstdchange(QString)));
though I added emitsignal in slots-header but I have this error;
Object::connect: No such slot Second::emitthesignal(QString) in ..\untitled\second.cpp:10
Sorry for taking long. I am new to qt and it takes time to understand thank you again.
-
@qtross said in Calling a Function when a Signal is Emitted from Another Class:
connect(this, SIGNAL(textForCombo(QString)),main, SIGNAL(TextReceive(QString)));
To use Signals & Slots effectively, the pattern should always be:
connect(member, SIGNAL(x), this, SLOT(y));
to achive loose coupling. Other way round your objects are harder to re-use.Object::connect: No such slot Second::emitthesignal(QString) in ..\untitled\second.cpp:10
This error message has nothing to do with this connect, IMHO:
connect(this, SIGNAL(emitsignal(QString)), this, SLOT(forstdchange(QString)));
Also, you should check out the new connect syntax:
https://doc.qt.io/qt-5/signalsandslots.html
https://wiki.qt.io/New_Signal_Slot_SyntaxRegards
-
Hi again, I updated my code, it seems logical now but I still could not make it work.
I must be missing something simple or doing still something silly.I also uploaded:
https://ufile.io/dambwl0c
Ui screens:
https://ibb.co/xC6gqTzand There is my code;
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_pushButton_clicked(); void addtoCombo(QString text); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h" #include "ui_mainwindow.h" #include "secondclass.h" #include <QDebug> #include <iostream> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); SecondClass* second = new SecondClass; connect(second, SIGNAL(update(const QString)), this, SLOT(addtoCombo(const QString))); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { SecondClass* window = new SecondClass; window->show(); } void MainWindow::addtoCombo(QString text) { qDebug() <<"I have been called" << endl; ui->comboBox->addItem(text); ui->stackedWidget->setCurrentIndex(1); }
secondclass.h:
#ifndef SECONDCLASS_H #define SECONDCLASS_H #include <QWidget> namespace Ui { class SecondClass; } class SecondClass : public QWidget { Q_OBJECT public: explicit SecondClass(QWidget *parent = nullptr); ~SecondClass(); private: Ui::SecondClass *ui; signals: void update(const QString text); private slots: void on_pushButton_clicked(); }; #endif // SECONDCLASS_H
seconclass.cpp
#include "secondclass.h" #include "ui_secondclass.h" SecondClass::SecondClass(QWidget *parent) : QWidget(parent), ui(new Ui::SecondClass) { ui->setupUi(this); } SecondClass::~SecondClass() { delete ui; } void SecondClass::on_pushButton_clicked() { emit update("it adds"); }
-
@qtross said in Calling a Function when a Signal is Emitted from Another Class:
jup, the problem is you do not connect the signal to the instance that is shown.
in your constructor you create a SecondClass instance
{
ui->setupUi(this);
SecondClass* second = new SecondClass;
connect(second, SIGNAL(update(const QString)), this, SLOT(addtoCombo(const QString)));}
and on pushbutton clicked, you create yet an other instance of your SecondClass and show that one.
But this one has no connects to it!void MainWindow::on_pushButton_clicked()
{
SecondClass* window = new SecondClass;
window->show();}
make
SecondClass* second
a member of your main window.h//Constructor than changes to ui->setupUi(this); second = new SecondClass; connect(second, SIGNAL(update(const QString)), this, SLOT(addtoCombo(const QString)));
void MainWindow::on_pushButton_clicked() { second->show(); }
-
@J.Hilk , it worked finally, Thank you so much!