Можно долго программировать десктопные приложения и работать только с одним потоком, не испытывая необходимости в использовании еще одного потока. И это нормально.
Но вот например понабилось вам опрашивать свой сайт (периодически) для получения заданий для программы. И тут второй поток напрашивается на 100 процентов, чтобы не тормозить работу основного (пользовательского) потока.
В Qt второй поток создается очень просто и данными обмениваться между потоками тоже очень просто, так как механизм сигнал-слот потоко защищённый. Это означает, что вызов сигнала помещается в очередь событий потока (как бы).
После создания потока ему можно передавать об'екты для владения. То есть создаём экземпляр какого-то класса и делаем ему moveToThread.
Смысл в том, что все создаваемые классы в коде создаются изначально только в главном потоке приложения.
После перемещения созданного об'екта класса в дочерний поток этот об'ект уже не будет обрабатывать события главного потока и что точно он будет делать это обрабатывать события дочернего потока.
Но мы можем из главного потока об'екту дочернего потока посылать сигналы, предварительно связав их через сигнал-слот конечно же. Только связь должна быть Quered , но не Direct.
Далее поток надо запустить, делается это командой start.
Далее есть небольшой нюанс и заключается он в том, что поток по умолчанию вызывает свой метод run , который в цикле обрабатывает события от ОС и внутренние события, использует стандартно QEventLoop.
Так вот это метод run виртуальный и вы его должны заменить на свой. В переопределенном run вы например можете реализовывать запросы к внешнему серверу через класс QNetworkAccessManager. На
Прикрепляю небольшой демонстрационный проект внизу.