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

d26162e03445cd249b5de6bae2769607

Многих этим не удивишь, но всё-таки хочу поделится большой радостью ибо наконец-то сделал универсальное всплывающее окно (на 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, то можно особо не переживать о составе возвращаемого результата, ведь вы можете вернуть в качестве результата любой свой об'ект.

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

© Habrahabr.ru