Как стать автором
Обновить

Окно индикации какого-то процесса на Qt

Уровень сложностиСредний
Время на прочтение3 мин
Количество просмотров3.8K

Многих этим не удивишь, но всё-таки хочу поделится большой радостью ибо наконец-то сделал универсальное всплывающее окно (на Qt) для индикации (логгирования) хода выполнения каких-то долгих команд (далее будем называть условно команда1234).

Основная идея универсальности в вызове у объекта слота по наименованию , передача параметров через QVariant (до 10шт.), возврат результата тоже через QVariant.

Все это реализуется без проблем через вызов метода invokeMethod.

Через параметры QVariant мы можем передавать и возвращать все , что угодно - какие-то свои классы, главное не забыть в конце определения таких классов добавлять макрос Q_DECLARE_METATYPE (имя вашего класса).

Теперь об самом окне. Окно основано на QDialog и должно запускать свой метод exec, чтобы перехватывать все события от ОС на чаоперационной системы иначе окно не сможет в реальном режиме времени себя отрисовы скроллингавать, чтобы обновлять логгируемую информацию внутри себя.

У нас информация помещается в QLabel, но это не суть. Просто QLabel может выводить html форматированный текстовый лог (RichText). Это просто для красоты.

Есть такой нюанс, что мы не можем одновременно запустить exec и команду1234 (в одном потоке). И мы не хотим городить огород из двух потоков.

Поэтому мы сначала делаем инициирование отложенно по таймеру запуска команды1234 (кстати именно этот прием практиковали троли везде где только можно), а потом вызываем exec диалога.

Да конечно ещё до exec надо связать сигнал вывода лога ( у нас sig_log) выполняемого объекта (которому принадлежит команда1234) и слот окна для приема сообщения (у нас slot_log).

И второй сигнал напрашивается это завершение выполнения процесса (у нас sig_finished) с параметром ошибка есть/нет. Допустим если ошибка есть и мы оставляем висеть окно лога на экране, если нет тихо закрываем.

Вкратце и весь подход.

В чем основное удобство дальнейшего использования. В коде команды1234 , обычно вызывается множество функций, вложенных друг в друга, с многочисленными ветвлениями для отработки различных ситуаций, мы теперь где надо просто добавляем emit sig_slot(..) и все. То есть нам не надо дополнительно в функции передавать какие-то параметры ссылки,указатели для возврата значений ошибок и городить прочий огород. Тут явная демонстрация преимуществ технологии сигнал/слот.

Когда мы завершаем процесс успешно мы вызываем sig_finished без ошибки. Везде где у нас процесс вылетает с ошибкой мы испускаем sig_finished с описанием ошибки. И это реально просто становится удобно, то есть не надо особо думать, например, обрыв связи с оборудованием, значит тут в коде делаем sig_finished с описанием "обрыв связи".

В итоге мы создаём одну простую универсальную функцию (у нас называется call_slot) для вызова выполнения команд типа 1234 с индикацией хода выполнения.

И ещё надо отметить об универсальности, поскольку мы возвращаем QVariant, то можно особо не переживать о составе возвращаемого результата, ведь вы можете вернуть в качестве результата любой свой объект.

Проект на гитхабе

Для программиста есть выгода от такого подхода, выгода в том что в коде команды1234 вы возвращаете (как уже говорилось) как результат любой класс, структуру и т.д. Но вот в функциях вызываемых из команды1234 (а их там вложенно обычно немало, для отработки разных результатов выполнения процесса) вам можно возвращать только bool и не надо передавать ссылки (как параметры в функции) для возврата каких-то результатов. В общем там все решается уже только испусканием сигналов sig_log и (когда надо) sig_finished. То есть надо добавить отработку какого-то еще одного неуспешного результата - вставил где тебе показалось это логичным sig_log/sig_finished и ничего не сломал в программе.

Теги:
Хабы:
Всего голосов 6: ↑2 и ↓40
Комментарии43

Публикации

Истории

Работа

Программист С
29 вакансий
QT разработчик
9 вакансий

Ближайшие события

12 – 13 июля
Геймтон DatsDefense
Онлайн
14 июля
Фестиваль Selectel Day Off
Санкт-ПетербургОнлайн
19 сентября
CDI Conf 2024
Москва