Порядок разработки многопоточного приложения с QThread. Cоздадим проект Application->Qt ->Console Application. Мы будем пользоваться консольным приложением для того, чтобы понять, как использовать потоки, вообще. Проект назовем Threads. В мастере приложения оставляем все по умолчанию. Сгенерировался прототип приложения, некоторый шаблон. Для начала давайте сделаем так, чтобы он запускался в терминале нашей среды разработки и попробуем посмотреть, что происходит. Запускаем. Видим Application output. , который пока ничего не содержит. Обратите внимание, что приложение продолжает работать, хоть и является консольным, потому что запущен цикл обработки событий exec().
Для начала сделаем какую-нибудь заготовку, чтобы видеть, что приложение делает. Например, создадим бесконечный цикл с помощью конструкции forever. В теле цикла сделаем небольшую паузу, используя класс QTest и метод qSleep, скажем полсекунды. Для этого подключим QTest и не забудем добавить в QT += testlib в файл проекта. Напечатаем какой-нибудь текст на консоли, и будем инкрементировать переменную и выводить ее значение. Запуск. Теперь наше приложение последовательно генерирует числа.
Наше текущее приложение выполняет QTest::qSleep и qDebug в основном потоке. Это не очень удобно, например, если мы захотим печатать не только цифры, но и ещё что-нибудь. К примеру, разные счетчики с разной скоростью должны генерировать разные значения. Нам сложно будет придумать такую логику, которая в одном потоке сможет это сделать. Поэтому давайте попытаемся создать простой класс - наследник QThread и запустим ту же самую деятельность в несколько потоков, заодно разобравшись как эти потоки отличать один от другого.
Каким образом это делается? Создаем новый класс, допустим он будет называться PrintThread, базовый класс у него будет QThread, можно включить QObject. Давайте посмотрим на его объявления. Вот у него такой конструктор [4:18]. Добавим параметры Qstring, префикс и int тайм аут, с которым мы будем печатать.
Соответственно, меняем прототип нашей функции, заведем префикс, заведем тайм аут, и реализуем это в конструкторе. Для того, чтобы наш класс стал настоящим потоком, нам надо переопределить функцию run, она у нас protected, выглядит она
void run()
Давайте мы её реализуем. Можно просто перенести наш код из основного потока функции main. Требуется создать два объекта класса PrintThread, для этого включим его в наш основной файл. Создадим два экземпляра а и b. В таком виде они не захотят собираться, потому, что им что-то надо передать в конструктор. К примеру, а будет называться "А" и будет работать с интервалом 300 миллисекунд, а другой b назовем "В" и работать будет с интервалом 600 миллисекунд. Проставим двоеточие, так как это префикс. Попробуем это снова собрать и запустить: a.start() и b.start(). Запускаем и видим, что поток A и В выводит что-то в консоли, но видно, что А выводит почаще, и счетчик А быстрее меняется. Можно остановить и посмотреть текущий момент. Мы получаем более менее регулярное распределение событий вывода А и В на консоль.