Дмитрий
March 21, 2019, 4:57 p.m.

Проброс std::array<qint32, SIZE> с помощью сигнала по ссылке

qt, std::array, signal, Slot

Всем привет!

Хочу с помощью сигнала пробросить в слот массив std::array.
Делаю следующее:

  1. using fft_mag_arr= std::array<qint32, SIZE>;
  2. Q_DECLARE_METATYPE( fft_mag_arr );
  3.  

в конструкторе класса вызываю

  1. qRegisterMetaType<fft_mag_arr>();

само объявление сигнала:

  1. signals:
  2. void fft_mag_out(fft_mag_arr &fftmag, uint size);

Слот объявлен так (так можно в данном случае, если в сигнале fft_mag_arr?)

  1. void slotFunc(std::array<qint32, SIZE> &arr, uint size);

При запуске приложения при вызове сигнала пишет:
QObject::connect: Cannot queue arguments of type 'fft_mag_arr&' (Make shure 'fft_mag_arr&') is registered using qRegisterMetaType().

Как мне пробросить ссылку на std::array с помощью сигнала?
Спасибо

3

Do you like it? Share on social networks!

14
Evgenii Legotckoi
  • March 21, 2019, 5:03 p.m.

Добрый день

Тут скорее регистрация мета типа не полная. Нет его имени.

Напишите так

  1. qRegisterMetaType<fft_mag_arr>("fft_mag_arr");
    Дмитрий
    • March 21, 2019, 5:25 p.m.

    Попробовал, но не помогло.

      Evgenii Legotckoi
      • March 21, 2019, 5:36 p.m.

      Ну не знаю, кое-где на форумах встречается вариант с typedef вместо using

      1. typedef std::array<qint32, SIZE> fft_mag_arr;

      А вообще вполне закономерный вопрос, а зачем вам qRegisterMetaType? Слоты и сигналы и так работают с ссылками на std::vector без всякой метамагии.

      Так должно работать,

      1. signals:
      2. void fft_mag_out(std::array<qint32, SIZE> &arr, uint size);
      3.  
      4. public slots:
      5. void slotFunc(std::array<qint32, SIZE> &arr, uint size);

      Да и так тоже

      1. signals:
      2. void fft_mag_out(fft_mag_arr &arr, uint size);
      3.  
      4. public slots:
      5. void slotFunc(fft_mag_arr &arr, uint size);

      Там qRegisterMetaType ни к чему по сути, это нужно для работы QVariant, да регистрации в QML. И ещё ряда более редких случаев.

        Дмитрий
        • March 21, 2019, 5:47 p.m.

        typedef тоже не помог.

        Я сначала и написал все без qRegisterMetaType. Но начало вылетать предупреждение. Пришлось вставить.

          Evgenii Legotckoi
          • March 21, 2019, 5:48 p.m.
          • (edited)

          Какое предупреждение? Предупреждение - это не ошибка. Если вам статический анализ в Qt Creator что-то показывает, то это не значит, что это руководство к действию.

          В Qt Creator используется статический анализатор clang, который ничего не знает о сигналах и слотах в полной мере.

            Александр Панюшкин
            • March 21, 2019, 5:54 p.m.

            Добрый день. Вопрос, может не совсем в тему. А зачем вы используете такой контейнер? Передавать контейнер со статическим размером через сигнал/слот мне кажется не очень удобным.
            Я, конечно, понимаю, что вы его через дефайн заносите, но всё равно вам значит в разные классы заголовочный файл с этим дефайном тащить приходится.
            Если вы за память переживаете - можно взять вектор (std::vector или QVector) и зарезервировать под него память и передавать его размер через отдельную переменную, как у вас и сделано.
            Может после этого и все проблемы решатся. И не нужно будет с этой ошибкой биться.

            Хотя, возможно, у вас какая-то логика, которую я не вижу, которая требует именно такой тип контейнера.

              Дмитрий
              • March 21, 2019, 5:56 p.m.

              Дело в том, что слот не вызывается.

                Evgenii Legotckoi
                • March 21, 2019, 5:59 p.m.
                • (edited)

                Лучше действительно сделайте через вектор с выделением заранее заданного размера памяти, как Александр посоветовал, и тогда всё заработает.

                Иначе так слишком переусложните логику на ровном месте.

                  Тут мне код достался написанный. Объявляется обычный массив и в сигнале кидается указатель на него, а в слоте уже пробегаются по этому массиву. Хотлось бы избавиться от этого и по ссылке передавать массив. Но, может, я и зря пытаюсь все привести на более высокий уровень. А так да, можно и вектор использовать.

                    Evgenii Legotckoi
                    • March 21, 2019, 6:10 p.m.

                    Если там не настолько критично потребление памяти. То есть если это Desktop, а не встраиваемое решение или какой-нибудь игровой/графический движок. То проще будет на вектор переписать. Меньше головной боли.

                      Дмитрий
                      • March 21, 2019, 7:36 p.m.

                      ПО работает на малине. Попробовал сделать отдельный проект с парой классов. Один емитит вектор, второй его принимает. Все работает. На компе установлена 5.12.1. На малине Qt 5.3.2 как выяснилось. Не может же быть бага в Qt?
                      Дело еще в том, что сигнал с массивом емитится из другого потока, в котором запущен таймер, по таймауту которого и емитится массив. Врядли это с потоками связано?

                        Дмитрий
                        • March 22, 2019, 5:48 p.m.
                        • The answer was marked as a solution.

                        Проблему решил. Попробовал вектор по ссылке передавать, но ошибка была та же. Передача вектора в сигнале по константной ссылке решила проблему. Все работает и без qRegisterMetaType. Похоже, что это из-за того, что сигнал и слот в разных потоках.

                          Evgenii Legotckoi
                          • March 22, 2019, 5:52 p.m.

                          Скорее всего. Вам бы на всякий случай ещё и мюьтексами в слоте закрываться, если не сделано это

                            Дмитрий
                            • March 22, 2019, 6:29 p.m.

                            Да, мьютекс добавил, но в том потоке, где сигнал вызывается.

                              Comments

                              Only authorized users can post comments.
                              Please, Log in or Sign up
                              • Last comments
                              • IscanderChe
                                April 12, 2025, 5:12 p.m.
                                Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
                              • AK
                                April 1, 2025, 11:41 a.m.
                                Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
                              • Evgenii Legotckoi
                                March 9, 2025, 9:02 p.m.
                                К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
                              • VP
                                March 9, 2025, 4:14 p.m.
                                Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
                              • ИМ
                                Nov. 22, 2024, 9:51 p.m.
                                Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…