Название: Прога на ваш суд Отправлено: labview от Август 11, 2010, 21:43 Написал первую в жизни прогу с Qt (не без помощи этого форума). Раньше программировал на графическом языке программирования, где всё по-другому. Так что C/C++ я знаю только из далека (когда то в течении полугода программировал микроконтроллеры на си).
Так вот, решил сделать прогу для пробы, в ней задействованы сигналы и слоты, QThread и скачаная мной библиотека QExtSerialPort. Мне очень интересно услышать ваше мнение по поводу качаства программирования, услышать много советов по улучшению. Сама прога представляет из себя терминал для комуникации через последовательный порт (наподобии Windows Hyperterminal). Для проверки проги потребуются два последовательных порта и один Crossover - кабель для соединения этих двух портов. На крайняк должно хватить одного порта, тогда нужно соединить пины 2 и 3 и в терминале должно отбображаться эхо, то есть что печатаем, то и видим. Програ скомпилирована под 7 виндой 64 бит и пентиумом. Все сырцы (включая внешнюю библиотеку) прилагаются. Спасибо. http://labviewportal.eu/download/file.php?id=5884 (http://labviewportal.eu/download/file.php?id=5884) ЗЫ размер вложения не должен превышать 500 КБ, поэтому прогу выложил в своём форуме, а сырцы здесь. Название: Re: Прога на ваш суд Отправлено: QCasper от Август 12, 2010, 00:39 И не глючит? На вскидку - в реализации класса, который выполняется в отдельном потоке ни одного объекта синхронизации.
Или может я что-то не так понял... В чём интрига? :) Название: Re: Прога на ваш суд Отправлено: labview от Август 12, 2010, 01:05 Спасибо за первый отклик.
Не глючит? Это вопрос? У меня вроде не глючит, тестил недолго и только на двух компах, поэтому попросил потестить вас. Да, отдельный поток конкретно здесь, в этой проге, в принципе лишний. В Qt есть встроенный отдельный ивент луп (event loop) и это меня радует. Вообще то, во всех моих рабочих проектах программе приходится общатся параллельно по нескольким интерфейсам, так вот чтобы одно от другого не зависело, я создаю на каждый прибор свой поток. Ну и здесь по привычке для интерфейса сделал свой поток. Если бы я программировал не на Qt(где как я понял уже есть event loop), мне бы тоже пришлось создавать два потока, чтобы обработка событий и чтение с порта не зависели друг от друга и нажатие на кнопку не зависало. Ну а вобщем так, для тренировки попробовал использовать QThread, уверен он мне ещё понадобится. А что на счёт синхронизации? Как раз её я здесь не счёл нужной, т.к. данные приходящие с порта нужны только для представления юзеру. И юзер всё равно не успеет заметить изменение данных на лицевой панели быстрее чем за 100 мс. Какие способы (обьекты) для синхронизации Вы имели в виду? Название: Re: Прога на ваш суд Отправлено: kuzulis от Август 12, 2010, 08:14 2 QCasper
Цитировать И не глючит? На вскидку - в реализации класса, который выполняется в отдельном потоке ни одного объекта синхронизации. Или может я что-то не так понял... В чём интрига? Улыбающийся В принципе не нужны тут никакие объекты синхронизации. Что с чем хотите синхронизировать то? Читает из порта то ведь всегда один поток (run), а пишет в порт другой (главный). Тем более, в библиотеке QExtSerialPort (если мне не зменяет память) уже все операции I/O мьютексом разграничены. 2 labview Цитировать Так вот, решил сделать прогу для пробы, в ней задействованы сигналы и слоты, Ну, для этой либы (v 1.2) уже есть GUI терминал (см. qt-apps.org). Поищите.... Мне очень интересно услышать ваше мнение по поводу качаства программирования, услышать много советов по улучшению. Сама прога представляет из себя терминал для комуникации через последовательный порт (наподобии Windows Hyperterminal). ... Цитировать QThread и скачаная мной библиотека QExtSerialPort. Либа древняя как Г мамонта. Более новая ее интерпретация тут: http://code.google.com/p/qextserialport/ . Тем более, если устраивает лицензия GPL - то есть и другая библиотека QSerialDevice, в которой это все реализуется проще и т.п. Цитировать Да, отдельный поток конкретно здесь, в этой проге, в принципе лишний. В принципе, да, поток для этой задачи лишний. Но если в будущем необходимо будет писать что-то другое - то потоки пригодятся.Цитировать Если бы я программировал не на Qt(где как я понял уже есть event loop), ... Для версии библиотеки v 1.2 event loop вам не поможет!Еще: 1. Вечно в цикле в run проверять на наличие байт в порту - не есть красиво. Для этого есть другие способы. 2. У вас в программе чтение происходит в потоке run, а вот запись - в главном потоке , так что если юзер захочет передать тыщупицот байт данных, то GUI затормозит у вас! Резюме: В принципе, для начала не плохо. Название: Re: Прога на ваш суд Отправлено: mkv от Август 12, 2010, 08:59 Привет!
по коду, что мне сразу бросается в глаза: 1. в конструкторе SerialThread инициализацию portIsOpen и exitThread можно сделать в списке инициализации и значением true (а не TRUE)... в с++ есть тип bool: 2. this в тех случаях, что у тебя использовать не нужно 3. параметры в функции нужно передавать по ссылке и если они не изменяются по сделать их константными (это вообще относится ко всем переменным которые ты не будешь изменять... так проще читать код) 4. char buff[1024]; старайся избегать фиксированных буферов, вместо этого: QByteArray buff; buff.resize(newBufferSize); 5. port->read(buff, numBytes); а если даных в буфере будет больше 1024? 6. если используешь отдельный тред для работы с ком портом можно использовать блокирующее чтение... msleep будет не нужен... вообще sleep ИМХО это моветон. 7. emit SettingsWidget::stop(); или просто emit stop(); 8. во всех случаях с new: te = new MyTextEdit; лучше явно указать родителя: te = new MyTextEdit(this); 9. void quit(void); для плюсов void quit(); з.ы. прогу не запускал... Название: Re: Прога на ваш суд Отправлено: labview от Август 12, 2010, 13:29 Либа древняя как Г мамонта. Более новая ее интерпретация тут: http://code.google.com/p/qextserialport/ . Тем более, если устраивает лицензия GPL - то есть и другая библиотека QSerialDevice, в которой это все реализуется проще и т.п. Спасибо, скачал либу от туда, но ведь версия совпадает (v1.2 beta). Какая новее? Вообще всем огромное спасибо. Буду потихоньку дальше отвечать/спрашивать. Вот кстати прога, написаная на LabVIEW меньше чем за пол дня для себя в проф. интересах. Ну и заодно решил выложить её публике: http://labviewportal.eu/ru/kommunikacija-s-priborami/100-rs232-terminal Название: Re: Прога на ваш суд Отправлено: labview от Август 12, 2010, 16:07 1. Вечно в цикле в run проверять на наличие байт в порту - не есть красиво. Для этого есть другие способы. 2. У вас в программе чтение происходит в потоке run, а вот запись - в главном потоке , так что если юзер захочет передать тыщупицот байт данных, то GUI затормозит у вас! 1. я понимаю что есть другие способы чтения с порта не используя поллинг, а используя таймаут. Но для этого нужно знать протокол передачи данных (например из скольки байт состоит пакет, syncByte и прочее или например terminationChar), а здесь мы имеем дело с неопределённым протоколом. 2. не очень понимаю. У меня запись не происходит в главном потоке. Главный поток инициирует сигнал на запись, а сама запись происходит в event loop потока SerialThread. Название: Re: Прога на ваш суд Отправлено: kuzulis от Август 12, 2010, 18:00 Цитировать 1. я понимаю что есть другие способы чтения с порта не используя поллинг, а используя таймаут. Но для этого нужно знать протокол передачи данных (например из скольки байт состоит пакет, syncByte и прочее или например terminationChar), а здесь мы имеем дело с неопределённым протоколом. Нет, есть такая штука, как события от порта. При ее применении незачем постоянно мониторить порт на предмет bytesAvailable(). Цитировать 2. не очень понимаю. У меня запись не происходит в главном потоке. Главный поток инициирует сигнал на запись, а сама запись происходит в event loop потока SerialThread. Проверьте. Название: Re: Прога на ваш суд Отправлено: labview от Август 12, 2010, 18:12 1. мне думаю вполне хватит port->read(buff, numBytes) и значения Timeouts в настройках порта(при условии если знать сколько байт нужно считывать). Но про ивенты порта думаю узнать не помешало бы. Они реализовано в этой библиотеке?
2. даже не знаю как проверить, я думал, что слот это не просто функция класса, которую можно вызвать из другого потока. Ведь обьект port в главном потоке неизвестен, т.к. инстанциирован в SerialThread. Разве у потоков не разделённые области памяти? Спасибо. Название: Re: Прога на ваш суд Отправлено: kuzulis от Август 12, 2010, 20:09 Цитировать мне думаю вполне хватит port->read(buff, numBytes) и значения Timeouts в настройках порта(при условии если знать сколько байт нужно считывать). Но про ивенты порта думаю узнать не помешало бы. Они реализовано в этой библиотеке? Вы наверное не так поняли... Причем тут read и Timeouts ? Я говорю вам про то что нет смысла в потоке постоянно опрашивать порт на предмет того, пришли или нет в него данные. т.е. код: Код: ... не нужен! В той Qext что на google code есть жалкое подобие. :) (QSerialDevice лучше в этом отношении). А хотя, что вам говорить то? Смотрите сами код. :) Цитировать даже не знаю как проверить, я думал, что слот это не просто функция класса, которую можно вызвать из другого потока. Ведь обьект port в главном потоке неизвестен, т.к. инстанциирован в SerialThread. Разве у потоков не разделённые области памяти? натыкайте в main(), перед write(), перед read() код типа: Код: ... и увидите, что ID потока main() и при выполнении write() будут совпадать! :) Название: Re: Прога на ваш суд Отправлено: labview от Август 12, 2010, 20:29 1. я всё же не согласен с тем что использование ивентив порта конкретно в этой программе принесёт полезность. Я прекрасно понимаю что проверка данных в буфере это поллинг, но ведь у меня есть sleep на 100 мс. Т.е. в случае если данные накопились максимально за 100 мс пока я спал, то считываем и отправляем их все вместе.
В случае с ивентами мы бы получали ивент автоматически, при появлении данных в порте (обычно сразу после первого байта). Но зачем пользователю видеть каждый приходящий байт по их поступлению в порт? Это только загрузит процессор, т.к. комп должен апдейтить окно чаще. Может быть я что то не понимаю, если можно предложите Ваш вариант с использованием ивентов. Ну или просто опишите словами замену вышестоящего куска кода. Спасибо! 2. нужно бы проверить, для меня это очень важно!!! |