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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: про потоки и таймеры в QT4  (Прочитано 13177 раз)
itan
Гость
« : Октябрь 04, 2006, 14:50 »

[QT4.2.0] У меня такая проблема: есть ActiveX компонет, который экспортит нужные мне данные в Word. После того как я его вызываю:
Код:
reportCreator->dynamicCall("CreateWordDocument(const QString&, const QString&)", "c:/test.doc", "c:/test.xml");

интерфейс замораживается на продолжительное время. Вообще, хотелось бы иметь вместо этого хотя бы анимированный GIF, показывающий что процесс жив! Вопрос в том как это сделать? Можно ли определить вызов dynamicCall в отдельный поток ? или лучше воспользоваться QTimer ? и если да, то как?
Записан
bigirbis
Гость
« Ответ #1 : Октябрь 04, 2006, 14:55 »

Можно сделать проще:
- почкануть поток с месадж-боксом
- вызвать dynamicCall в основном потоке
- застрелить тот поток по окончании работы dynamicCall.
Топорно, но... если сделать наоборот, пользователь не осилит ситуацию и статанет процесс еще раз
Записан
itan
Гость
« Ответ #2 : Октябрь 04, 2006, 16:51 »

Цитата: "bigirbis"
Можно сделать проще:
- почкануть поток с месадж-боксом
- вызвать dynamicCall в основном потоке
- застрелить тот поток по окончании работы dynamicCall.
Топорно, но... если сделать наоборот, пользователь не осилит ситуацию и статанет процесс еще раз

не понял тебя, что значит "почкануть поток с месадж-боксом" ? Вообще-то я хотел что бы виджет с анимацией продолжал работать, во время вызова dynamicCall.
Записан
atak
Гость
« Ответ #3 : Октябрь 04, 2006, 19:02 »

Цитата: "itan"
не понял тебя, что значит "почкануть поток с месадж-боксом" ? Вообще-то я хотел что бы виджет с анимацией продолжал работать, во время вызова dynamicCall.

Этот месадж-бокс и будет виджетом, который анимацию станет показывать...
Записан
Dendy
Гость
« Ответ #4 : Октябрь 04, 2006, 21:31 »

Создать дополнительньІй поток с сообщением не получится. ВиджетьІ могут бьІть созданьІ только в основном (GUI) потоке.

Попробуй сделать вьІзов dynamicCall() в отдельном потоке.
Записан
Alex03
Гость
« Ответ #5 : Октябрь 05, 2006, 06:24 »

А вынести в отдельное приложение (по сути оно у Вас так и есть) и пользовать QProcess?
Записан
bigirbis
Гость
« Ответ #6 : Октябрь 05, 2006, 08:41 »

Цитировать
А вынести в отдельное приложение (по сути оно у Вас так и есть) и пользовать QProcess?

Не серьезно.

Цитировать
Создать дополнительньІй поток с сообщением не получится. ВиджетьІ могут бьІть созданьІ только в основном (GUI) потоке.

Согласен, лажанулся. Надо наоборот. Только, чтобы виджет получился модальный.
Записан
itan
Гость
« Ответ #7 : Октябрь 05, 2006, 08:46 »

Цитата: "Dendy"
Создать дополнительньІй поток с сообщением не получится. ВиджетьІ могут бьІть созданьІ только в основном (GUI) потоке.

Попробуй сделать вьІзов dynamicCall() в отдельном потоке.

Делаю так:
Код:
class TestThread : public QThread
{
public:
TestThread(QObject *parent = 0);
~TestThread();

protected:
void run();

private:
QAxObject* reportCreator;
};

TestThread::TestThread(QObject *parent)
:QThread(parent)
{
reportCreator = new QAxObject("{98C51056-5414-46E9-8FAD-E59099AFFF25}");
}

TestThread::~TestThread()
{
delete reportCreator;
};

void TestThread::run()
{
reportCreator->dynamicCall("CreateWordDocument(const QString&, const QString&)", "c:/test.doc", "c:/test.xml");
}  

далее в программе:
Код:
m_thread.start();

Вообщем, ActiveX начинает выдавать непонятные ошибки. В Debug Output пишется: QAxBase: Error calling IDispatch member CreateWordDocument: Exception thrown by server

Цитировать
А вынести в отдельное приложение (по сути оно у Вас так и есть) и пользовать QProcess?


Имеешь ввиду пересобрать компонент в EXE-шник, а потом запускать его и в командной строке указывать имя процедуры и ее параметры?
Записан
bigirbis
Гость
« Ответ #8 : Октябрь 05, 2006, 08:54 »

А что за объект такой ты контролировать собрался, если даже гугл на запрос
{98C51056-5414-46E9-8FAD-E59099AFFF25}
не выдает ниодного ответа?
Записан
Alex03
Гость
« Ответ #9 : Октябрь 05, 2006, 08:56 »

Цитата: "bigirbis"
Цитировать
А вынести в отдельное приложение (по сути оно у Вас так и есть) и пользовать QProcess?

Не серьезно.


Просто строка
Код:
reportCreator->dynamicCall("CreateWordDocument(const QString&, const QString&)", "c:/test.doc", "c:/test.xml");

Наводит на мысль что есть что-то типа MS офиса или генератора отчёта стороннего разработчика, а их наверняка можно запускать как отдельный процесс. Ну а по отслеживанию состояния дочернего процесса у QProcess всё есть! Улыбающийся

Ежели не так - звиняйте! Улыбающийся
Записан
itan
Гость
« Ответ #10 : Октябрь 05, 2006, 08:59 »

Цитата: "bigirbis"
А что за объект такой ты контролировать собрался, если даже гугл на запрос
{98C51056-5414-46E9-8FAD-E59099AFFF25}
не выдает ниодного ответа?


Это самописный компонет, наши программисты делали, все исходники для него у меня есть.
Записан
Alex03
Гость
« Ответ #11 : Октябрь 05, 2006, 09:06 »

Цитата: "itan"

Цитировать
А вынести в отдельное приложение (по сути оно у Вас так и есть) и пользовать QProcess?


Имеешь ввиду пересобрать компонент в EXE-шник, а потом запускать его и в командной строке указывать имя процедуры и ее параметры?


Зависит от того чей это компонент.
Но в общем случае да.
Записан
bigirbis
Гость
« Ответ #12 : Октябрь 05, 2006, 09:17 »

Вообще, мы буквально недавно нечто подобное проворачивали. QAxObject не очень подошел, достаточно геморройно, хотя определенных успехов даже на нем достигли. Мы разделили задачу на 2 процесса, но из-за того, что модуль работы с COM был представлен отдельным проектом, написанным на c#.

добавлено спустя 2 минуты:

 Кстати, вот пример я публиковал:
http://prog.org.ru/forum/htopic_3523_qaxobject.html
Записан
itan
Гость
« Ответ #13 : Октябрь 05, 2006, 14:14 »

Вообщем, перспективы складываются безрадужные. Пробывал разморозить окно следующим образом:
Код:
t= new QTimer(this);
connect(t, SIGNAL(timeout()), CMyWidget, SLOT(update()));
t.start(50);

reportCreator->dynamicCall(...)

не получается.

Пытался запихнуть обновление по таймеру в отдельный поток:
Код:
void TestThread::run()
{
QTimer timer;
timer.setInterval(50);  
connect(&timer, SIGNAL(timeout()), m_widget, SLOT(update()), Qt::DirectConnection);  

timer.start();  

exec();  
}  
тоже ничего...
Есть еще идеи?
Записан
Alex03
Гость
« Ответ #14 : Октябрь 05, 2006, 14:36 »

itan. Вы по всей видимости не понимаете принципов современных событийных приложений. Сигналы от таймера будут вызываться только тогда когда вы вернёте управление в цикл обработки сообщений. А оно у Вас в reportCreator->dynamicCall(...) блокируется.

void TestThread::run()
{
 ....
 reportCreator->dynamicCall(...)
 ....
}

А в GUI-главном потоке делаете что хотите.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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