Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++ Qt
Войти
Регистрация
Восстановить пароль
 
monnzz
0 / 0 / 0
Регистрация: 10.05.2012
Сообщений: 34
1

Запуск QTimeLine в QtConcurrent

11.12.2016, 14:28. Просмотров 349. Ответов 5
Метки нет (Все метки)

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

Ниже код создания и запуска потоков, он работает нормально:
C++ (Qt)
1
2
3
4
5
std::vector<QFuture<void>> threadResults;
    for(int i = 0; i < blantsToKill.size(); ++i) {
        threadResults.push_back(QtConcurrent::run(this, &GameManager::killBlant, std::ref(blantsToKill[i])));
    }
    std::for_each(threadResults.begin(), threadResults.end(), std::bind(&QFuture<void>::waitForFinished, std::placeholders::_1));
А вот здесь проблема, функция выполняется, но не происходит вызовов слотов. Слоты существуют и в одном потоке работают нормально, проблема именно в случае когда функция void Blant::die() выполняется в дочернем потоке, timeline либо не отправляет сигналы, либо они не доходят до обработчика. Ставил qDebug() в слоте, подтверждаю, что слот не вызывается.

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
void Blant::die()
{
    QTimeLine* timeLine = new QTimeLine(m_animationMoveTime);
    timeLine->setUpdateInterval(100);
    timeLine->setDuration(400);
    connect(timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animateDying(qreal)));
    connect(timeLine, SIGNAL(finished()), this, SLOT(finishDying()));
    timeLine->start();
    
    // чтоб функция не вернулась раньше того как закончилась анимация.
    delay(400 + 100 * 2);
}
Без дочерних потоков все работает нормально, просто злодеи умирают друг за другом, а хотелось бы чтоб они помирали вместе.

Буду признателен, если кто объяснит в чем проблема, ну или предложит идею получше.

 Комментарий модератора 
Код C++/Qt обозначается с помощью тега CPPQT.
Правила именования тем и оформления сообщений в разделе Qt

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.12.2016, 14:28
Ответы с готовыми решениями:

QtConcurrent
Здравствуйте, хочу сделать сервер многопоточным, через concurrent. Делаю так void...

QtConcurrent и bind
Доброго времени суток. Есть вот такой незамысловатый код: #include &lt;QCoreApplication&gt; #include...

Не работает QtConcurrent
void Object::loadObjModel(const std::string filename) { .... std::string line; ...

QtConcurrent::mapped
Заранее извиняюсь. Вопрос достаточно глупый, но всё же QStringList lst (QStringList ( ) &lt;&lt; &quot;one&quot;...

Использование в qtconcurrent::run() ui->
Доброго времени, форумчане! При сабже программа вылетает. Как быть? Возможно ли из лямбды послать...

5
nmcf
6531 / 5755 / 2621
Регистрация: 14.04.2014
Сообщений: 24,493
11.12.2016, 15:22 2
Для взаимодействия потоков через сигналы в connect() должно быть указано QueuedConnection.
1
monnzz
0 / 0 / 0
Регистрация: 10.05.2012
Сообщений: 34
11.12.2016, 17:10  [ТС] 3
nmcf, спасибо за ответ, но к сожалению, не помогло.
C++ (Qt)
1
2
connect(timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animateDying(qreal)), Qt::DirectConnection);
connect(timeLine, SIGNAL(finished()), this, SLOT(finishDying()), Qt::DirectConnection);
Однако в случае DirectConnection
C++ (Qt)
1
2
connect(timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animateDying(qreal)), Qt::DirectConnection);
connect(timeLine, SIGNAL(finished()), this, SLOT(finishDying()), Qt::DirectConnection);
Слот вызывается, но при этом возникает следующая ошибка:
Код
QObject::startTimer: Timers cannot be started from another thread
Не подскажите, как это понять? Ведь QTimeLine создается именно в этом потоке.
0
nmcf
6531 / 5755 / 2621
Регистрация: 14.04.2014
Сообщений: 24,493
11.12.2016, 17:32 4
Это к таймеру относится, а не к этому.
1
monnzz
0 / 0 / 0
Регистрация: 10.05.2012
Сообщений: 34
11.12.2016, 20:42  [ТС] 5
хм, просто у меня больше нет других счетчиков времени.

Добавлено через 2 часа 36 минут
В общем, ситуация следующая:

Qt GUI class instances can only be used in the main thread, i.e. the one started when your app starts. Possibly QTimeLine also falls into this category. In any case, you won't be able to access QGraphicsItem instances from a different thread, and updates to GUI class instances will always occur in the order in which the main event loop calls their paintEvents. You can't update different things on the GUI simultaneously no matter what.

In the main thread you -can- use the Qt animation framework to nearly simultaneously make changes to your two bad guys by reworking your QTimeLine into QAbstractAnimation instead.
Так что, если кто-то столкнется с моей ситуацией, в несколько потоков апдейтить ваш gui не получится и QTimeLine вероятно тоже нельзя использовать.
0
nmcf
6531 / 5755 / 2621
Регистрация: 14.04.2014
Сообщений: 24,493
11.12.2016, 20:45 6
Отправлять сигналы можно, нельзя интерфейсные объекты туда перемещать.
0
11.12.2016, 20:45
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.12.2016, 20:45

О странностях QtConcurrent+QFuture+QFutureWatcher
Вот такой код работает: QString threadFunc() { return QString(&quot;This is result&quot;); } ...

Вызов QtConcurrent приводит к зависанию GUI
Суть проблемы: есть две кнопки, по клику запускается выполнение простой процедуры в отдельном...

Ошибки при работе потока в QtConcurrent
Добрый день. Столкнулся со странной проблемой. Программа должна обсчитать координаты для 2-х колец....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru