D
Dragon00117 травня 2017 р. 13:15

Com порт,поток и другое

Здравствуйте. Возникло несколько вопросов и не совсем хватает опыта их решить.

1. Есть com порт, его настройки я задаю в основном GUI, после чего создаю объект для работы с com-порт,создаю новый поток,запихиваю в поток объект.
Получается два потока: основной(GUI) и второй(для работы с com-портом).
В этом потоке я принимаю сообщения от com-порта и после делаю обработку.
Возник вопрос,как можно сделать,что-то вроде запрета на прием данных?
То есть, у меня есть данный коннект

connect(&thisPort, &QSerialPort::readyRead,this, &TPort::ReadInPort);
который выполняет слот по получению данных, в котором происходит обработка данных.
Мне нужно как-то залочить прием,пока не обработались данные.
Думал насчет стека очереди. Все таки хотелось узнать мнение профессионала.

И второй вопрос.
2) При обработка данных с com-порта, мы делаем запрос в БД и проверяем количество пришедших значений, если пришел 1 значение, то тут проблем нету, но если будет >1, мне необходимо открыть widget по верх всех окон, но тут возникает проблема, т.к. GUI работает в первичном потоке, нам нет доступа к нему без сигнала, но если использовать сигнал, то в случае,если в GUI будет открыто диалоговое окно, то оно не сработает. Мне нужно,чтобы при любых условиях открылось данный widget, поверх всех открытых окон.
Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

5
Evgenii Legotckoi
  • 18 травня 2017 р. 00:15

День добрый.

1) По первому вопросу

С таким функционалом я особо не работал, но встречался с подобным при работе с сетью, поэтому выскажу свои мысли.

Нужно сразу буферизировать данные. Если они не большие, то можно использовать какой-нибудь QList, и использовать компаратор по дате , например, или использовать QVector, но так, чтобы забирать и складывать данные по принципу первый вошёл - первый вышел . По приёму данных записывать их в этот буффер. По записи в буффер вызывать сигнал о том, что была сделана запись. По которому уже забирать данные из буффера. Если учесть, что com-порт у вас в отдельном потоке, то буффер стоит сделать в главном потоке. Информацию передавать по сигнал/слотовому соединению. Остаётся тогда проблема в том, как сообщить программе, что в буффере что-то есть. Думаю, что также можно кидать сигнал из буффера, что данные были приняты. А дальше уже реализовывать разбор данных из буффера с удалением обработанных данных.

Можно также для буфферизации использовать базу данных, например, SQLite, если объёмы данных достаточно большие, а поступают они не очень часто.

Ещё я посмотрел бы в сторону QBuffer и производных классов, думаю, что должно подойти, но придётся наследоваться от него и переопределять некоторые методы. К сожалению, с ним почти не работал.

2) По второму вопросу

Если я понял правильно, то обработку данных и запрос к БД вы делаете в потоке COM-порта. В этом и проблема с окном. Но если сделать буффер в main потоке, то есть в потоке GUI, и сделать там же обработку данных, то станет уже несколько проще, поскольку можно будет не только открывать окно, но и добавлять информацию в открытое окно, также через сигналы и слоты соответственно. То есть, если виджет ещё не открыт, то открываем его, если уже открыт, то обновляем информацию в данном виджете. Виджет тогда нужно объявить в заголовочном файле и чтобы один его экземпляр существовал и к нему были подключены соответствующие сигнал/слотовые соединения.

Пока такие мысли у меня, естественно в процессе workflow что-то измените, а что-то усложните в данной концепции. Но обработку данных, считаю стоит убрать из потока, где крутится класс COM-порта. Пускай он только принимает данные и отправляет их в основной поток программы. А там уже будет буфферизация и остальная обработка.

    D
    • 18 травня 2017 р. 07:02
    Насчет первого вопроса, наверно я не правильно подумал о использование какого-либо буффера/листа. У меня есть сканер штрих кода, который считывает некоторый абонемент со штрих кодом (типа "1111111"), если использовать некоторый буффер, в который будет складироваться все значения приходящие, то возникает такая проблема, если человек,много раз со сканирует, программе придется несколько раз проверять одно и тоже, что черевато, т.к. у меня некоторая система пропуска,если он много раз со сканирует, то много раз и откроется.
    Может быть все таки есть,какая нибудь задержка? может быть сделать как-то хитро, что-то вроде еще одного слота + переменная типа bool, при приходе данных,мы вызываем данный слот, проверяем переменную,если она не true, просто выходим, иначе прогоняем?

    Насчет второго вопроса, то есть, в потоке gui,создать окно,его скрыть, при необходимости его показать и обновить данные, но если будет открыто диалоговое окно, откроется ли данный виджет?
    Если убрать обработку данных с потока com-порта,в основной, не помешает ли это работе? Просто у меня есть окно некого администратора (основной gui, в котором работает пользователь), ему никак не должно мешать, то что обрабатывается данные пришедшие с com-порта, одно условие, это выпадение окна поверх всех с некоторой информацией, после проверки в БД.
      Evgenii Legotckoi
      • 18 травня 2017 р. 10:07

      1) Задержку можно реализовать с помощью того же самого таймера, в самом классе, который отвечает за считывание данных. И игнорировать все входящие данные в течение определённого периода. Либо сделать временное хранилище с тем же самым QMap, в котором в качестве ключа будет храниться уникальный идентификатор штрихкода с временем жизни. То есть в качестве ключа будет Id штрихкода, а в качестве значения - время жизни. При считывании данных проверять наличие id в QMap, если он есть, то смотреть время жизни. Если не истекло, значит игнорировать обработку, если истекло, значит можно считать повторно. Время жизни установить допустим 15 секунд для считывания.

      2) Вообще, если виджет подразумевается как окно, то может открыться, как таковой проблемы в этом нет. Что касается того, что помешает ли работе gui, то может быть, но если учесть уточнение по работе программы из первого вопроса, то я уже не вижу большой необходимости в переносе буфера в main, можно и там оставить.

        D
        • 18 травня 2017 р. 15:17

        1. Таймер тут к сожалению не подойдет, т.к. не известно сколько времени нужно будет,а брать слишком малое черевато. QMap тоже не подойдет, посетитель может зайти и позже, но если он будет в контейнере, может сработать не верно,я все таки думаю сделать, через переменную.
        2. Вот тут разобрался, вроде все заработало
        Спасибо большое вам за вашу помощь.

          Evgenii Legotckoi
          • 19 травня 2017 р. 02:40

          1. Тогда сначала нужно описать все возможные дозволенные варианты поведения посетителя и потом уже отталкиваться от них. Поскольку начинается такая ситуация:
          -Давайте сделаем задержку.
          -А если посетитель уйдет?
          -А если посетитель вернётся?
          -т.д.
          Нужно описать все эти если, то есть написать User Story фактически на этот кейс. И уже на основе него думать над возможным функционалом и решением.

            Коментарі

            Only authorized users can post comments.
            Please, Log in or Sign up
            AD

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

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

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

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

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

            • Результат:20бали,
            • Рейтинг балів-10
            Останні коментарі
            ИМ
            Игорь Максимов22 листопада 2024 р. 11:51
            Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
            Evgenii Legotckoi
            Evgenii Legotckoi31 жовтня 2024 р. 14:37
            Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
            A
            ALO1ZE19 жовтня 2024 р. 08:19
            Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
            ИМ
            Игорь Максимов05 жовтня 2024 р. 07:51
            Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
            d
            dblas505 липня 2024 р. 11:02
            QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
            Тепер обговоріть на форумі
            Evgenii Legotckoi
            Evgenii Legotckoi24 червня 2024 р. 15:11
            добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
            t
            tonypeachey115 листопада 2024 р. 06:04
            google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
            NSProject
            NSProject04 червня 2022 р. 03:49
            Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
            9
            9Anonim25 жовтня 2024 р. 09:10
            Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

            Слідкуйте за нами в соціальних мережах