Qt нет такого слота для метода - PullRequest
0 голосов
/ 08 октября 2019

Я пытаюсь выучить Qt (используя CMake / c ++). Вот кусок кода, который я написал. Я пытаюсь использовать функциональность подключения. Там нет ошибки компиляции. Я также использовал следующую команду для повторного создания файла moc.

moc -o moc_SimulationRunner.cpp SimulationRunner.h

Однако я все еще получаю эту ошибку во время работы моего проекта:

QObject :: connect: такого слота нет. SimulationRunner :: _ OpenFileDialog (file_address)

мой заголовочный файл:

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 = "");

  };

и мой файл cpp:

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;
  }

Ответы [ 2 ]

3 голосов
/ 08 октября 2019

Аргументы (подпись) сигнала и слота должны совпадать.

Если вы используете старый синтаксис на основе строк , вы должны определить аргументы в SIGNAL ()и SLOT () макросы. Например, вы можете подключиться, например, так:

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

Вы не можете подключиться к слоту с большим количеством или другими аргументами. Однако вы можете подключиться к слоту с меньшим количеством аргументов, например, так:

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

Если вы используете новый синтаксис QT5 (что рекомендуется, так как он должен предупреждать вас уже при компиляции)вам не нужно указывать аргументы самостоятельно:

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

Обход QT5 / C ++ 11
Для передачи другого аргументаВы можете подключить лямбда-функцию к сигналу, в котором вы вызываете слот или функцию. Итак, чтобы передать ваш QLineEdit:

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

Дополнительные пояснения:
Новый синтаксис
Аргументы по умолчанию

1 голос
/ 08 октября 2019

Вы неправильно понимаете значение аргумента в соединении.

подпись вашего слота

OpenFileDialog(QLineEdit*, std::string);

и подпись вашего соединения -

OpenFileDialog(QLineEdit*)

, поэтому вы получаете предупреждение. Вы не вызываете функцию (так что ее можно разрешить с помощью параметра по умолчанию), вы указываете на функцию , поэтому подпись должна совпадать.

Совет:если вам не нужно использовать Qt4, используйте синтаксис подключения Qt5:

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

для вашего конкретного случая:

, если вы всегда передаете file_address в свой слот, затем просто удалите аргумент изслот и использовать его прямо в корпусе.

В противном случае, если вы используете Qt4, единственным обходным решением является создание дополнительного слота с вызовом без объекта.

Qt4 way:

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

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

Qt5 way, используйте лямбду:

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