Russian Qt Forum
Ноябрь 23, 2024, 10:49 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Параллельный поток  (Прочитано 12394 раз)
Eugene K
Гость
« Ответ #15 : Декабрь 18, 2019, 00:35 »

В 4.1 есть moveToThread(). его можно как-то использовать? все таки не просто так он должен быть.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #16 : Декабрь 18, 2019, 00:50 »

В 4.1 есть moveToThread(). его можно как-то использовать? все таки не просто так он должен быть.

Да, я же говорю - надо, чтобы нитка крутила event loop. К сожалению, кутешники не сразу придумали как делать грамотно и до 4.4 метод run() был чисто виртуальным, поэтом без наследования было никак (а я уж и запамятовал).
Но фиксится это тривиально - тупо вызываете exec() внутри run() и всё - это ровно то, что делает QThread начиная с 4.4 и поэтому этот "новый" класс наследовать не надо.

В общем случае, наследоваться от треда плохо, потому что туда начинают писать бизнес-логику и размывается граница что где, то есть какой метод в каком потоке зовется. Когда есть разделение на Worker и QThread с exec'ом всё очевидно - методы треда (start, quit) зовутся из главного потока, методы Worker'а зовутся из потока QThread'а. С главным потоком Worker общается через сигнал-слоты.  То есть, есть разделение по данным => не надо явных мьютексов и иных механизмов синхронизации.

То есть вам нужен такой хелпер
Код:
struct Thread: public Thread
{
    explicit Thread(QObject *parent = 0) : QThread(parent) {}
protected:
    void run() { (void)exec(); }
};

А дальше всё как в примере с воркером
« Последнее редактирование: Декабрь 18, 2019, 01:01 от Авварон » Записан
Eugene K
Гость
« Ответ #17 : Декабрь 18, 2019, 02:12 »

Cделал так:

frmMain.h:

Код:
struct Thread: public QThread
{
    explicit Thread(QObject *parent = 0) : QThread(parent) {}
public:
    void run() { (void)exec(); }
};


class frmMain : public QWidget, public Ui::MainWindow
{
    Q_OBJECT


public :
    frmMain();
    ~frmMain();

    Thread thread1;

}

frmMain.cpp
(главная форма и главное окно):

Код:
frmMain::frmMain() : QWidget(0, Qt::Window)
{
connect(pushButton_6, SIGNAL(clicked()), SLOT(count1()));


this->moveToThread(&thread1);
connect(&thread1, SIGNAL(started()), this, SLOT(countch()));
}


void frmMain::count1()
{
thread1.start();
}


void frmMain::countch()
{
//вывод данных на экран
}

все равно главное окно заморожено



Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #18 : Декабрь 18, 2019, 10:02 »

В 4.1 есть moveToThread(). его можно как-то использовать? все таки не просто так он должен быть.

Но зачем использовать старое и высохшее 4.1 ?
Найдется там еще баг и как с этим жить ?

Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #19 : Декабрь 18, 2019, 12:33 »

Cделал так:

Вы упорно продолжаете игнорировать совет использовать отдельного воркера Грустный

Код:
this->moveToThread(&thread1);
Так делать неправильно (хотя это и можно заставить работать, у меня на работе везде так Злой). У вас есть окно, оно создает тред и владеет им (с тз разрушения объектов), но вы его "перемещаете" внутрь треда, то есть как бы теперь тред "владеет" (с логической точки зрения) окном. Окно владеет тредом который "владеет" окном. Рекурсия, однако.
И в этом не было бы ничего плохого, кроме того, что опять не понятно, в каком потоке какой метод должен вызываться (и ваши проблемы это подтверждают).
Вот например, вы переместили окно в тред и теперь все слоты (по идее) должны вызываться в потоке. В том числе count1(), который стартует поток. Но ведь поток еще на запущен! Вопрос - в каком потоке вызовется этот слот (и вызовется ли?). Я не знаю, дебагать неправильно написанный код мне лень.
Еще, возможно, ваше окно вообще никуда не переместилось, потому что виджеты нельзя перемещать в треды (by design они должны жить в главном потоке). В консоли вы должны видеть что-то типа
Цитировать
QObject::moveToThread: Widgets cannot be moved to a new thread
Записан
Eugene K
Гость
« Ответ #20 : Декабрь 18, 2019, 13:35 »

Авварон, я не игнорирую совет, я не знаю пока как использовать отдельного воркера.
Я и написал сюда, потоиу, что с потоками не знаком как оказалось. Раньше работал через потоки таймеров и другого не надо было.

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

А то примеры из интернета то ошибки выдают, то не работают.

Возможно дело в версии 4.1.
Версию 4.1 использую по старинке, не было времени переходить на новую. Не знал, что будут такие проблемы. На крайний случай придется на 4.8 переходить, т.к. QtConcurrent с 4.7 идет. Но это надо будет адаптировать программу, а написано немало.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #21 : Декабрь 18, 2019, 15:06 »

Вы на меня не тратьте много времени, а то мне уже неудобно, лучше приведите работающий фрагмент создания параллельного потока типа нажал на кнопку - на экране печатается текст с паузами и в это время можно другие кнопки нажимать (как из моего фрагмента выше).
Ну ладно, купили на "неудобно" Улыбающийся Аттач. Там нет завершения нитки (разберетесь). Старый синтаксис SLOT/SIGNAL оставил, но если что другое не пойдет на древней версии - проблемы Ваши. Заметьте что нитки должны общаться только сигналами, не пытайтесь лезть к виджетам напрямую из воркера - это рухнет. Ну и если "по-взрослому" то, как сказали выше, никакие QThread здесь не нужны, лучше заюзать штатный тул который сам их сделает

Мне надо создать хотя бы один работающий поток для начала, дальше, думаю, разберусь.
Ох уж это "программирование на примерах"  Улыбающийся
Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #22 : Декабрь 18, 2019, 16:08 »

Версию 4.1 использую по старинке, не было времени переходить на новую.

какая выдержка и терпение !

Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #23 : Декабрь 18, 2019, 16:38 »

этой версии наверное уже лет 10, если не больше? Улыбающийся
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #24 : Декабрь 18, 2019, 16:43 »

этой версии наверное уже лет 10, если не больше? Улыбающийся

Больше, я когда пытался вчера по исходникам найти когда же там run перестал быть виртуальным, выяснил что это было в 4.4, а история в гите начинается с 4.5 в 2009м году. То есть 10-11 лет - это 4.5, а то мамонтово еще древнее Подмигивающий
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #25 : Декабрь 18, 2019, 17:51 »

этой версии наверное уже лет 10, если не больше? Улыбающийся

Qt_version_history Qt_4: 4.1 - 20 December 2005.

Через пару дней паспорт получать может Улыбающийся.
Записан

Пока сам не сделаешь...
Eugene K
Гость
« Ответ #26 : Декабрь 18, 2019, 20:22 »

.
« Последнее редактирование: Декабрь 19, 2019, 07:32 от Eugene K » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #27 : Декабрь 18, 2019, 20:46 »

Боже, ну неужели так самому самому допилить. Проверьте вариант в аттаче
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.054 секунд. Запросов: 23.