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