ДК
Джон Кофи4 марта 2020 г. 8:14

Передача сигнала в функцию

Qt, signals

Привет. Можно ли передать в метод сигнал, как параметр и потом сделать коннект на него? код ниже конечно не работает.

_model->waitingFor(SIGNAL(Model::somesignal())); // no matching function for call to..

...
class Model : public QObject
{
    Q_OBJECT
public:
    explicit Model(QObject *parent = nullptr);

    void foo();
    void waitingFor(const char *signal); - не работает
//    void waitingFor(std::function<void()> &signal); - тоже не работает

signals:
    void somesignal();
};
...
void Model::waitingFor(const char *signal)
{
    QEventLoop evloop;
    connect(this, signal, &evloop, &QEventLoop::quit); // не соберется
    connect(this, SIGNAL(signal()), &evloop, SLOT(quit())); // соберется, но QObject::connect: No such signal Model::signal()
    evloop.exec();
}

*так тоже не работает

void Test::waitingFor2(std::function<QMetaMethod> &signal)
{
    QEventLoop evloop;
    connect(this, signal, &evloop, &QEventLoop::quit);
    evloop.exec();
}
Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

6
Evgenii Legotckoi
  • 4 марта 2020 г. 8:51
  • (ред.)
  • Ответ был помечен как решение.

Добрый день.

Можно передать сигнал, но лучше в виде указателей это всё делать, МАКРОСЫ следует изживать из проекта.

Также здесь следует использовать шаблоны. Конкретно ваш случай можно разрулить так

#ifndef MODEL_H
#define MODEL_H

#include <QEventLoop>

class Model : public QObject
{
    Q_OBJECT
public:
    explicit Model(QObject *parent = nullptr) : QObject(parent) {}

    template<typename TSignal>
    void waitingFor(TSignal&& signal)
    {
        QEventLoop evloop;
        connect(this, signal, &evloop, &QEventLoop::quit);
        evloop.exec();
    }

signals:
    void someSignal();
};

#endif // MODEL_H

И вызов метода

model->waitingFor(&Model::someSignal);
    ДК
    • 4 марта 2020 г. 9:05

    великолепно. я уж начал сомневаться, что делаю решаемую задачу.

      Evgenii Legotckoi
      • 4 марта 2020 г. 9:10

      На макросах тоже можно, но лучше не надо. Кода больше получается, сам код в случае макросов требует применения SFINAE - в общем красивым код не назовёшь. Да и макросы менее надёжны.

        ДК
        • 4 марта 2020 г. 13:54
        • (ред.)

        на работе просто собрал, а протестил вот сейчас дома- не отрабатывает коннект.

        class Test : public QObject
        {
            Q_OBJECT
        public:
            explicit Test(QObject *parent = nullptr) : QObject(parent) {}
        
            void foo()
            {
                qDebug() << "foo";
                emit somesignal();
            }
        
            template<typename TSignal>
            void waitingFor(TSignal &&signal)
            {
                qDebug() << "waitingFor";
                connect(this, signal, [](){ qDebug() << "signal received"; });
            }
        
        signals:
            void somesignal();
        };
        ...
        _test->foo();
        _test->waitingFor(&Test::somesignal);
        

        именно qDebug() << "signal received";
        Может нельзя передавать в метод сигнал, а потом соединяться с ним?

          ДК
          • 4 марта 2020 г. 14:20

          я вот думаю, что всё же правильней передавать const char *. Но всё равно тишина...

          class Test : public QObject
          {
              Q_OBJECT
          public:
              explicit Test(QObject *parent = nullptr) : QObject(parent) {}
          
              void foo()
              {
                  QTimer *timer = new QTimer;
                  timer->setSingleShot(true);
                  timer->start(5000);
                  connect(timer, &QTimer::timeout, timer, &QTimer::stop);
                  emit somesignal();
              }
          
              static void waitingFor(QObject *sender, const char *signalFromObj)
              {
                  qDebug() << "waitingFor";
                  QEventLoop loop;
                  connect(sender, signalFromObj, &loop, SLOT(quit()));
                  loop.exec();
              }
          
          signals:
              void somesignal();
          };
          ...
          _test->foo();
          Test::waitingFor(_test, SIGNAL(somesignal()));
          qDebug() << "mainwindow";
          

          qDebug() << "mainwindow"; не отработает.

            Evgenii Legotckoi
            • 4 марта 2020 г. 14:38
            • (ред.)

            я вот думаю, что всё же правильней передавать const char *. Но всё равно тишина...

            Вы неправильно думаете. При компиляции проектов на C/C++ макросы разворачиваются в полноценный код, а в случае Qt присутствует ещё и этап создания moc файлов, в которых эти макросы уже интерпретируются в сигнатуры функций и создаётся код коннектов. И только потом уже происходит компиляция всех созданных исходников. В Qt не создаются налёту подключения сигналов и слотов из указателей на const char *, потому что SIGNAL и SLOT - это не строки, это макросы. Весь процесс создания кода в случае SIGNAL и SLOT для сигналов и слотов происходит на этапе ПРЕДКОМПИЛЯЦИИ, а не в рантайме. А то, что вы пытаетесь передавать указатель на const char - это рантайм.

            Я вам дал полностью рабочий пример кода, который оттестировал и запустил.

            Вот модифицированный вариант, который тоже работает.

            #ifndef MODEL_H
            #define MODEL_H
            
            #include <QEventLoop>
            #include <QDebug>
            
            class Model : public QObject
            {
                Q_OBJECT
            public:
                explicit Model(QObject *parent = nullptr) : QObject(parent) {}
            
                template<typename TSignal>
                void waitingFor(TSignal&& signal)
                {
                    connect(this, signal, [](){ qDebug() << "Signal emitted"; });
                }
            
            signals:
                void someSignal();
            };
            
            #endif // MODEL_H
            
            

            Вот так его можно использовать

            widget.h

            #ifndef WIDGET_H
            #define WIDGET_H
            
            #include <QWidget>
            #include "model.h"
            
            QT_BEGIN_NAMESPACE
            namespace Ui { class Widget; }
            QT_END_NAMESPACE
            
            class Widget : public QWidget
            {
                Q_OBJECT
            
            public:
                Widget(QWidget *parent = nullptr);
                ~Widget();
            
            private slots:
                void on_pushButton_clicked();
            
                void on_sendSignalButton_clicked();
            
            private:
                Ui::Widget *ui;
            
                Model m_model;
            };
            #endif // WIDGET_H
            
            

            widget.cpp

            #include "widget.h"
            #include "ui_widget.h"
            
            Widget::Widget(QWidget *parent)
                : QWidget(parent)
                , ui(new Ui::Widget)
            {
                ui->setupUi(this);
            }
            
            Widget::~Widget()
            {
                delete ui;
            }
            
            void Widget::on_pushButton_clicked()
            {
                m_model.waitingFor(&Model::someSignal);
            }
            
            void Widget::on_sendSignalButton_clicked()
            {
                emit m_model.someSignal();
            }
            
            

            Вот тестовый проект

            CheckSignals.zip CheckSignals.zip

              Комментарии

              Только авторизованные пользователи могут публиковать комментарии.
              Пожалуйста, авторизуйтесь или зарегистрируйтесь
              AD

              C++ - Тест 004. Указатели, Массивы и Циклы

              • Результат:50баллов,
              • Очки рейтинга-4
              m
              • molni99
              • 26 октября 2024 г. 1:37

              C++ - Тест 004. Указатели, Массивы и Циклы

              • Результат:80баллов,
              • Очки рейтинга4
              m
              • molni99
              • 26 октября 2024 г. 1:29

              C++ - Тест 004. Указатели, Массивы и Циклы

              • Результат:20баллов,
              • Очки рейтинга-10
              Последние комментарии
              i
              innorwall14 ноября 2024 г. 19:03
              Qt/C++ - Урок 060. Настройка внешнего вида приложения в рантайме I didnt have an issue work colors priligy dapoxetine 60mg revia cost uk August 3, 2022 Reply
              i
              innorwall14 ноября 2024 г. 11:42
              Как Копировать Файлы в Linux If only females relatives with DZ offspring were considered these percentages were 23 order priligy online uk
              i
              innorwall14 ноября 2024 г. 9:09
              Qt/C++ - Урок 068. Hello World с использованием системы сборки CMAKE в CLion ditropan pristiq dosing With the Yankees leading, 4 3, Rivera jogged in from the bullpen to a standing ovation as he prepared for his final appearance in Chicago buy priligy pakistan
              i
              innorwall14 ноября 2024 г. 4:05
              EVILEG-CORE. Использование Google reCAPTCHA 2001; 98 29 34 priligy buy
              Сейчас обсуждают на форуме
              i
              innorwall14 ноября 2024 г. 3:39
              добавить qlineseries в функции priligy amazon canada 93 GREB1 protein GREB1 AB011147 6
              i
              innorwall11 ноября 2024 г. 10:55
              Всё ещё разбираюсь с кешем. priligy walgreens levitra dulcolax carbs The third ring was found to be made up of ultra relativistic electrons, which are also present in both the outer and inner rings
              9
              9Anonim25 октября 2024 г. 9:10
              Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…
              ИМ
              Игорь Максимов3 октября 2024 г. 4:05
              Реализация навигации по разделам Спасибо Евгений!

              Следите за нами в социальных сетях