H'H
H'H

Reputation: 1680

Qt no such slot for method

I am trying to learn Qt (using CMake/c++). Here is piece of code that I wrote. I am trying to use connect functionality. There is no compiling error. I used also following command to re-generate moc file.

moc -o moc_SimulationRunner.cpp SimulationRunner.h

However I am still receiving this error while running my project:

QObject::connect: No such slot SimulationRunner::_OpenFileDialog(file_address)

my header file is:

class SimulationRunner : public QWidget
  {
  Q_OBJECT

  public:
    explicit SimulationRunner(QWidget *parent = nullptr);

  private:
    QGroupBox *createFirstExclusiveGroup();

  private slots:
    bool _OpenFileDialog(QLineEdit* i_line_edit, std::string = "");

  };

and my cpp file is:

QGroupBox *SimulationRunner::createFirstExclusiveGroup()
  {
  QGridLayout *grid = new QGridLayout;
  ....

  QLineEdit *file_address= new QLineEdit();
  file_address->setPlaceholderText("File address");

  QPushButton *file_address_button = new QPushButton("Browse...");
  file_address_button ->setFixedWidth(75);

  grid->addWidget(file_address, 0, 0, 1, 1);
  grid->addWidget(file_address_button , 1, 1, 1, 1);

  group_box->setLayout(grid);

  QObject::connect(file_address_button , SIGNAL(clicked()), this, SLOT(_OpenFileDialog(file_address)));
  return group_box;
  }

bool SimulationRunner::_OpenFileDialog(QLineEdit* i_line_edit, std::string /* = "" */)
  {
  if (!i_line_edit)
    return false;

  QString filename = QFileDialog::getOpenFileName(
    this,
    "Open Document",
    QDir::currentPath(),
    "All files (*.*) ;; Document files (*.doc *.rtf);; PNG files (*.png)");

  if (!filename.isNull())
    {
    qDebug() << "selected file path : " << filename.toUtf8();
    }

  i_line_edit->setText(filename);
  return true;
  }

Upvotes: 0

Views: 859

Answers (2)

Moia
Moia

Reputation: 2364

You're misunderstanding the meaning of the argument in the connect.

the signature of your slot is

OpenFileDialog(QLineEdit*, std::string);

and the signature of your connect is

OpenFileDialog(QLineEdit*)

that's why you're getting the warning. You're not calling a function (so it can be resolved with the default parameter), you're pointing to a function, so the signature has to be the same.

Tip: unless you have to use Qt4, use the Qt5 connect syntax:

QObject::connect(file_address_button, &QPushButton::clicked, this, &SimulationRunner::OpenFileDialog);

for your specific case:

if you always pass file_address in your slot, then just remove the argument from the slot and use it directly in the body.

Otherwise, if you're using Qt4, the only workaround is to make an additional slot with the call with no object.

Qt4 way:

private slots:
void _dummySlot(){
   _OpenFileDialog(file_address);
}

  QObject::connect(file_address_button , SIGNAL(clicked()), this, SLOT(_dummySlot()));

Qt5 way, use lambda:

    QObject::connect(file_address_button, &QPushButton::clicked, this, [this](){
        _OpenFileDialog(address_name);
    });

Upvotes: 1

bunto1
bunto1

Reputation: 331

The arguments (signature) of the signal and the slot have to match.

If you use the old string-based Syntax you have to define the arguments in the SIGNAL() and SLOT() macros. So you could connect for example like this:

QObject::connect(file_address_button, SIGNAL(clicked(bool)), this, SLOT(_ExampleSlotFunction(bool)));

You cannot connect to a slot with more or different arguments. However you can connect to a slot with fewer arguments, e.g. like this:

QObject::connect(file_address_button, SIGNAL(clicked(bool)), this, SLOT(_AnotherExampleSlotFunction()));

If you use the new QT5 Syntax (which is recommended because it should warn you already when compiling) you don't need to specify the arguments yourself:

QObject::connect(file_address_button, &QPushButton::clicked, this, &ExampleClass::_ExampleSlotFunction);
QObject::connect(file_address_button, &QPushButton::clicked, this, &ExampleClass::_AnotherExampleSlotFunction);

QT5 / C++11 workaround
To pass a different argument, you could connect a lambda function to the signal, in which you call the slot or function. So to pass your QLineEdit:

QObject::connect(
    file_address_button, &QPushButton::clicked,
    this, [file_address]() { _OpenFileDialog(file_address); }
);

Further explanations:
New Syntax
Default Arguments

Upvotes: 3

Related Questions