Search code examples
c++qtqwidget

Qt pass variables between forms


I want to pass a string from a form that is opened by the first form to the first form. I am new to C++. Here is my code.

Form1.h // main form

#include "dialog.h"
namespace Ui {
class Form1;
}

class Form1 : public QMainWindow
{
    Q_OBJECT

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

void refresh(QString str_local);

private slots:
    void on_pushButton_clicked();

private:
    Ui::Form1 *ui;
    Dialog *dialog1;
};

// form1.cpp

void Form1::on_pushButton_clicked()
{
   dialog1= new Dialog;   //Create new form with other class
     dialog1->show();

     QObject::connect(dialog1, SIGNAL(change(str_remote)), this, SLOT(refresh(str_local)));   //Connect when is emit signal cambia in the child form and pass the string to local function
}


void Form1::refresh(QString str_local)
{
    qDebug() << "Back to main" << str_local;
    ui->label->setText(str_local);
}

// dialog.h the second form that should pass the value to main form ...

class Dialog : public QDialog
{
    Q_OBJECT
signals:
    void change(QString s);

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

private slots:
    void on_pushButton_clicked();

private:
    Ui::Dialog *ui;
};

// dialog.cpp ...

void Dialog::on_pushButton_clicked()
{
    QString name;
     name = ui->lineEdit->text();
     emit change(name);
     this->close();
}

I get the error: No such signal Dialog::change(str_remote) in ../Format/form1.cpp:22 .


Solution

  • You have some strange code in here:

    QObject::connect(dialog1, SIGNAL(change(str_remote)), this, SLOT(refresh(str_local)));
    
    • Since your class already inherits QObject indirectly, you can simply drop the scope specifier.

    • You probably aim for using the new compilation-time syntax signal-slot mechanism.

    • You have not marked your slot as slot in the header file.

    • You are trying to use the old signal/slot syntax with variable names for the signal and slot as opposed to the types.

    • Your signal is not using the good practice of const T& (i.e. constant reference).

    • You are specifying this explicitly, whereas it can be dropped. This is just admittedly personal taste.

    • You do not follow the Qt signal/slot naming convention, e.g. your signal is a verb rather adjective. It is also too generic, rather than "fooChanged" as the good practice goes.

    There are other issues in your code as well, but this time I only focused on that one line. I would use this line with modern Qt and C++ programming principles in mind:

    connect(dialog1, &Dialog::changed, (=)[const auto &myString] {
        ui->label->setText(myString);
    });
    

    However, since this requires CONFIG += c++14, if your compiler does not support that (e.g. VS2010), you can go for this:

    connect(dialog1, SIGNAL(change(const QString&)), this, SLOT(refresh(const QString&)));