Search code examples
c++qtc++11buttonsignals-slots

Pass a widget in argument of a SLOT


Here's what I want to do: I have a QLineEdit and a QPushButton. When I push the button I want to retrieve the text of the QLineEdit and do stuff with it. Unfortunately, I am struggling to do it because I'm kind of a newbie with Qt.

My mainwindow.cpp (simplified):

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

    QLineEdit *textInput = new QLineEdit();
    QPushButton *awesomeButton = new QPushButton();

    retrieveButton->setText("Click me");

    connect(awesomeButton, SIGNAL(released()), this, SLOT(awesomeFunction(QLineEdit)));

}

void MainWindow::awesomeFunction(QLineEdit myQLineEdit) {
    QString exploitedText = myQLineEdit.text();
    //DO STUFF
}

My mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include <QLineEdit>
#include <QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

public slots:
    void awesomeFunction(QLineEdit myQLineEdit);

private:
    QPushButton *awesomeButton;
    QLineEdit *textInput;
    Ui::MainWindow *ui;
};
#endif

There's nothing interesting in main.cpp. I am missing something but I don't know what. When I use this without any parameters to my function, it works fine. But when I try to pass a Widget in parameter it doesn't work. The documentation is well done but I can manage to find what I need over the internet.


Solution

  • There are a couple of problems with the code shown. Firstly QObject, and by implication anything that inherits from it, is non-copyable so you can't pass a QLineEdit by value: you need to pass by reference/pointer.

    Secondly the line...

    connect(awesomeButton, SIGNAL(released()), this, SLOT(awesomeFunction(QLineEdit)));
    

    should issue a runtime warning on the console because the slot expects an argument -- QLineEdit -- but the QPushButton::released signal doesn't provide one.

    Assuming the QLineEdit you're interested in is textInput then you can make use of the new Qt5 signal/slot syntax and a lambda. So change the awesomeButton signature to...

    void awesomeFunction(QLineEdit *myQLineEdit);
    

    and then connect to the signal with (untested)...

    connect(awesomeButton, &QPushButton::released, this,
            [this, textInput]()
              {
                awesomeFunction(textInput);
              });