Реклама

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

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

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

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

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

День добрый.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Реклама

Ответы

Только авторизованные пользователи могут отвечать на форуме.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь
Последние комментарии
  • EVILEG
  • 23 мая 2017 г. 12:26

Qt/C++ - Урок 005. QSqlRelationalTableModel - Работаем со связными таблицами

В классе DataBase указывается путь к базе данных. В данном случае C:/example/ и т.д. Так вот, у вас есть каталог example ?

  • EVILEG
  • 23 мая 2017 г. 12:19

Qt/C++ - Урок 029. Изображение в базе данных в Qt – Сохранение и Восстановление

Нет. не верно. Ошибка вот в этой строке: QPixmap inixmap = fileName; // Сохраняем его в изображение объекта QPixmap; Выше я показывал, как что нужно путь передавать в качестве аргумент...

Qt/C++ - Урок 029. Изображение в базе данных в Qt – Сохранение и Восстановление

QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "/home", tr("Images (*.png *.xpm *.jpg)")); QPixmap inixmap = fileName; // Сохраняем его в и...

Qt/C++ - Урок 005. QSqlRelationalTableModel - Работаем со связными таблицами

https://www.dropbox.com/sh/vhxcx0iyq0j4578/AACwgWPnZwNqGBndKESiXfFqa?dl=0

  • tetta
  • 22 мая 2017 г. 1:32

Qt/C++ - Урок 052. Кастомизация Qt Аудио плеера в стиле AIMP

Как сделать так, что бы только когда верхнюю полосу зажимаешь, то перетаскивалось окно и что бы оно оставалось на месте?

Сейчас обсуждают на форуме
  • tetta
  • 23 мая 2017 г. 17:59

Создание кнопки "new", "save" и "open". MDI. toolBar

void MainWindow::open(){ QString openFile = QFileDialog::getOpenFileName(this, tr("Open File"), "C:/", ...

Проверка наличия записи в БД при выполнении запроса

Код форм про которые говорил прикрепил. regrdit форма в которой отображается информация отбираемая из базы. editobject форма для редактирования

  • Arrow
  • 23 мая 2017 г. 13:41

qmake

Странно по сообщениям выдает, что у меня компилирутся 32 bit версия (x86 build). Компилятор опознан правильно и в ABI сам определилил x86-windows-msys-pre-64bit и исполняемый файл создае...

WinApi CBTProc

Да всех активных, тоесть через CBT.