QT: нет такого слота

Проблема в том, что я продолжаю получать ошибку времени выполнения «Нет такого слота» в Qt Creator каждый раз, когда я запускаю окно «Настройки» из своего главного окна. Я обнаружил, что Qt до сих пор был довольно нелогичным, и эта концепция слотов и сигналов кажется немного натянутой по сравнению с простой передачей переменных или вызовов функций. По сути, у меня есть меню с параметром настроек, при нажатии которого открывается окно настроек, в котором необходимо получить двойное значение от пользователя и обновить переменную в главном окне.

НастройкиWindow.h

class SettingsWindow : public QWidget
{
      Q_OBJECT
  public:
      SettingsWindow(QWidget *parent = 0);
  signals:
      void ValChanged(double newVal);
  public slots:
      void Accept();
  private:
      QLineEdit *le1;
};

В окне настроек есть кнопка принятия, которая вызывает Accept(), который выдает сигнал ValChanged с newVal, установленным как пользовательский ввод в le1 как двойной.

НастройкиWindow.cpp

void SettingsWindow::Accept(){
    emit ValChanged(le1->text().toDouble());
    this->close();
}

Это окно настроек вызывается главным окном приложения: MainWindow

MainWindow.cpp

class MainWindow : public QMainWindow
{
      Q_OBJECT  
  public:
      MainWindow(QWidget *parent = 0);
  public slots:
      void SetVal(double x);
  private slots:
      void NewWindow();
  private:
      double theVal;
};

В этом главном окне есть меню, из которого можно выбрать настройки. Это создает новое окно с полем для ввода числа.

MainWindow.cpp

void MainWindow::NewWindow()
{
    SettingsWindow *MySettings=new SettingsWindow(this);
    QObject::connect(MySettings, SIGNAL(ValChanged(double)), this, SLOT(SetVal(double)));
    MySettings->show();
    MySettings->raise();
}

void MainWindow::SetVal(double x){
    theVal = x;
}

Я надеюсь, что когда окно настроек открыто, пользователь может ввести val в поле, которое затем выдает сигнал ValChanged Signal, который устанавливает для Val значение, указанное пользователем. В большинстве случаев я видел проблему с тем, что люди не включали макрос Q_OBJECT, но я включал его оба раза. Любые предложения о том, почему это не работает?


person user850275    schedule 18.07.2011    source источник
comment
С файлом moc все в порядке? Вы видите свой слот в qt_metacall(QMetaObject::Call _c, int _id, void **_a) ?   -  person Thomas Vincent    schedule 18.07.2011
comment
Да, это там. Это все должно быть определено.   -  person user850275    schedule 18.07.2011
comment
Пара уточняющих вопросов. Какой слот указан в сообщении об ошибке Нет такого слота? Как называется слот Accept?   -  person Arnold Spence    schedule 18.07.2011
comment
Object::connect: Нет такого слота MainWindow::SetVal(двойной x)   -  person user850275    schedule 18.07.2011
comment
@ user850275: Либо вы неверно процитировали сообщение об ошибке, либо неправильно скопировали свой код. Сообщение об ошибке должно быть No such slot: MainWindow::SetVal(double) (без x). Если сообщение об ошибке правильное, и ваш код действительно SLOT(SetVal(double x)), вы можете решить проблему, удалив файл x.   -  person TonyK    schedule 19.07.2011


Ответы (4)


Проблема, с которой вы столкнулись, почти наверняка связана с тем, что файл moc не воссоздан, опечатка в вашем вызове для подключения или опечатка в объявлении рассматриваемого слота.

Вы можете принять во внимание, что это намного больше работы, чем необходимо для получения ввода из диалогового окна. Более простым методом было бы подключить сигнал нажатия кнопки «Принять» к слоту в главном окне, а затем получить нужное значение непосредственно из экземпляра окна настроек с помощью метода getXXX().

Если у вас в конечном итоге появится диалоговое окно настроек с большим количеством значений, вместо того, чтобы извлекать каждое значение через геттеры, сигнал кнопки «Принять» возвращает структуру со всеми значениями в виде полей этой структуры.

Я должен упомянуть, что похоже, что NewWindow() создает новый экземпляр SettingsWindow каждый раз, когда он вызывается. Все эти экземпляры будут существовать до тех пор, пока MainWindow не будет уничтожен.

person Arnold Spence    schedule 18.07.2011
comment
Хм, я подумаю над этим. Я бы хотел, чтобы кто-нибудь опубликовал это в учебниках или что-то в этом роде. Я также хорошо знаю, что из экземпляров, оставленных открытыми до деструктора MainWindow, это просто момент проверки концепции. - person user850275; 18.07.2011
comment
Я могу понять ваше разочарование, особенно если вы раньше не работали с оконными фреймворками. Это обширная библиотека, с которой нужно ознакомиться. Qt — одна из лучших документированных библиотек, которые вы найдете, и она богата примерами и демонстрациями. К сожалению, большинство из них сосредоточены на одном элементе и не имеют исчерпывающих примеров применения передового опыта. Иногда вы обнаружите, что одна из демонстраций или примеров будет иметь ценную информацию в качестве побочного эффекта. Программисты Qt здесь дружелюбны и готовы помочь, так что продолжайте задавать вопросы. - person Arnold Spence; 18.07.2011
comment
Ну спасибо за помощь! Я решил использовать описанный вами метод настройки геттера для выполнения работы, и теперь он работает. Считайте это решенным. - person user850275; 18.07.2011

Для меня добавление public Q_SLOTS: над функцией слота было тем, чего мне не хватало. (у меня уже был Q_OBJECT и т.д.)

person Cameron    schedule 16.10.2012
comment
Пожалуйста, укажите это. Мне непонятно, что именно вы сделали. - person dhein; 22.07.2015

Я решил свою проблему, когда вручную воссоздал свой файл moc в командной строке.

Я использовал параметр командной строки qt, поэтому все пути были установлены:

cd /path/to/my/project
moc -o moc_myheaderfile.cpp myheaderfile.h

В моем коде не было ничего плохого, и в моем make-файле не было ни одной команды moc, которую я мог видеть. Это работает для всех моих примеров, которые я пробовал. Я надеюсь, что кто-то может попробовать это тоже. Я экспериментировал почти 85 часов, прежде чем смог найти причину.

Для пользователей кодовых блоков попробуйте воссоздать ваши moc-файлы, чтобы быть точным. опция -o myheaderfile.cpp предназначена для сохранения вывода moc в файл. Запуск moc для файла фактически извергает все в окно консоли.

person Clement Osei Tano    schedule 15.05.2015

Я неправильно пытался передать параметр в свой слот без QSignalMapper, о чем я узнал из этого ТАК пост.

Удаление всех параметров функции слота (.h и .cpp) позволило найти и вызвать обратный вызов.

Да, я Qt n00b. Время рефакторинга с QSignalMapper :)

ХТН

person GraehamF    schedule 24.10.2013