Название: Запуск QtScript в отдельном потоке Отправлено: tzeentch16 от Октябрь 21, 2012, 16:32 Передо мной возникла такая задача: написать простой GUI редактор/интерпретатор сценариев языка, основаного на QtScript.
Проблема: невозможно прервать исполнение зависнувшего скрипта при помощи QScriptEngine::abortEvaluation(), так как GUI зависает. Решение: запихнуть исполнение в отдельный поток. Я никогда не писал многопоточные приложения, но делать нечего - начал кодить. Проблема в том, что я использую не QScriptEngine, а класс, унаследованный от него, но довольно криво написаный другим человеком. Кривость заключается в том, что должен быть только один экземпляр этого класса, и его нельзя копировать - иначе возникнут проблемы. Итак, я написал простенький пример, в котором я создаю поток, передаю в него указатель на некий dummy-класс EnginePlaceHolder, затем запускаю поток. Есть GUI для запуска и остановки потока - все отлично работает. Я обрадовался, но при попытке использовать вместо EnginePlaceHolder реальный ScriptEngine получаю тонну сообщений об ошибках от Qt: QApplication: Object event filter cannot be in a different thread. QObject::startTimer: timers cannot be started from another thread QApplication: Object event filter cannot be in a different thread. QObject::startTimer: timers cannot be started from another thread ... Скажите, никто никогда не сталкивался с задачей запустить QtScript в отдельном потоке? Как это можно сделать, если обьект движка нельзя копировать? Как можно безопасно передать обьект движка в поток выполнения (не копируя его), и выполнить сценарий в отдельном потоке, так, чтобы при этом GUI не зависал, и можно было бы прервать исполнение? Возможно, кто-то где-то что-то читал об этом, я 3 дня по интернету лазил, ничего не нашел, но вдруг... Зараннее спасибо. Название: Re: Запуск QtScript в отдельном потоке Отправлено: mutineer от Октябрь 21, 2012, 19:51 Покажи код своего примера, может видно будет где ты ошибся
Название: Re: Запуск QtScript в отдельном потоке Отправлено: tzeentch16 от Октябрь 21, 2012, 20:30 Вот исходники примера: thread-test.rar (http://narod.ru/disk/62760093001.8a8a66771bfa5d03376f7237f342ef6f/thread-test.rar.html). В нем ошибок нет, однако попытка использовать QScriptEngine вместо класса-путышки EnginePlaceHolder порождает большое количество сообщений об ошибках в консоли, потом программа зависает или падает.
Название: Re: Запуск QtScript в отдельном потоке Отправлено: Igors от Октябрь 22, 2012, 09:20 но довольно криво написаный другим человеком. Кривость заключается в том, что должен быть только один экземпляр этого класса, и его нельзя копировать - иначе возникнут проблемы. Не уверен что это кривость, вообще чужую корову охаять легко :)Не смотрел выложенный код, но первое что бросается в глаза - сделать moveToThread всем классам которые планируются в отдельной нитке. Поскольку moveToThread автоматычно срабатывает для чилдренов, вызовов потребуется немного. Судя по исходникам abortEvaluation() может быть вызван из главной нитки для прерывания Название: Re: Запуск QtScript в отдельном потоке Отправлено: mutineer от Октябрь 22, 2012, 10:30 Igors прав - ты не делаешь moveToThread и _engine продолжает жить там же, где и был создан - в главном треде
Название: Re: Запуск QtScript в отдельном потоке Отправлено: tzeentch16 от Октябрь 22, 2012, 16:15 Да, с moveToThread() все работает, спасибо вам большое.
Я сперва мало что про нее нашел, решил - она мне не поможет, а сейчас погуглил специально про нее, попался неплохой пример, теперь работает. |