Russian Qt Forum

Qt => Общие вопросы => Тема начата: Разуев Максим от Август 31, 2007, 13:11



Название: [Qt 4.3.1-Win-Com-vs2005] Как добраться до главного цикла программы
Отправлено: Разуев Максим от Август 31, 2007, 13:11
Вопрос такой: Мне надо вызывать определенную функцию в основном цикле обработки сообщений (после обработки событий). Каким образом это можно сделать.
Нужно это потому что у меня есть функционал вывода 3D обьекта в dll. Внутри библиотеки реализован рабочий цикл, ему для обеспечения нормального вывода необходимо синхронизироваться с циклом приложения. В чистой WinAPI программе вызывается специальная функция библиотеки внутри цикла сообщений.


Название: Re: [Qt 4.3.1-Win-Com-vs2005] Как добраться до главного цикла программы
Отправлено: alex12 от Сентябрь 01, 2007, 21:35
Если чистый WinAPI, то может это:
Код:
bool QCoreApplication::winEventFilter ( MSG * msg, long * result )   [virtual]

Вообще,думаю, копать надо в сторону QApplication или QCoreApplication.


Название: Re: [Qt 4.3.1-Win-Com-vs2005] Как добраться до главного цикла программы
Отправлено: Разуев Максим от Сентябрь 01, 2007, 23:16
Сообщения я и так нормально обрабатываю. Мне нужно вызывать одну определенную функцию внутри цикла сообщений.
Вообще это необходимо для корректного вывода библиотекой 3D сцены и обработки событий. Сейчас я вызываю эту функцию через таймер 100 раз в секунду, но работает не очень хорошо.


Название: Re: [Qt 4.3.1-Win-Com-vs2005] Как добраться до главного цикла программы
Отправлено: alex12 от Сентябрь 02, 2007, 00:55
Кстати, дергать функцию по таймеру мне думается нормальное решение. Таймер все равно работает, посылая сообщение в очередь. Только 100 мс многовато. Можно поставить чуть ли не 5 мс. Если таймер не успевает, то Qt эту ситуацию нормально отрабатывает.

На счет цикла сообщений: нужно в main() QCoreApplication::exec() заменть на свой цикл с QCoreApplication::processEvents(...).

Несколько цитат по теме:

QApplication:

Код:
int QCoreApplication::exec ()   [static]

Enters the main event loop and waits until exit() is called.
Returns the value that was set to exit()
(which is 0 if exit() is called via quit()).

It is necessary to call this function to start event handling.
The main event loop receives events from the window system
and dispatches these to the application widgets.

[b]To make your application perform idle processing
(i.e. executing a special function whenever there are no pending events),
use a QTimer with 0 timeout. More advanced idle processing
schemes can be achieved using processEvents().[/b]

See also quit(), exit(), processEvents(), and QApplication::exec().

QApplication:
Код:
void QCoreApplication::processEvents ( QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents )   [static]

Processes all pending events for the calling thread according to
the specified flags until there are no more events to process.

You can call this function occasionally when your program
is busy performing a long operation (e.g. copying a file).

Calling this function processes events only for the calling thread.

Note: This function is thread-safe.

See also exec(), QTimer, QEventLoop::processEvents(), flush(), and sendPostedEvents().

QTimer:
Код:
As a special case, a QTimer with a timeout of 0 will
time out as soon as all the events in the window system's
event queue have been processed. This can be used to
do heavy work while providing a snappy user interface:

     QTimer *timer = new QTimer(this);
     connect(timer, SIGNAL(timeout()), this, SLOT(processOneThing()));
     timer->start();

processOneThing() will from then on be called repeatedly.
It should be written in such a way that it always returns quickly
(typically after processing one data item) so that Qt can deliver
events to widgets and stop the timer as soon as it has done
all its work. This is the traditional way of implementing heavy
work in GUI applications; multithreading is now becoming
available on more and more platforms, and we expect that
zero-millisecond QTimers will gradually be replaced by QThreads.

Note that QTimer's accuracy depends on the underlying
operating system and hardware. Most platforms support
an accuracy of 1 millisecond, but Windows 98 supports
only 55. If Qt is unable to deliver the requested number
of timer clicks, it will silently discard some.


Название: Re: [Qt 4.3.1-Win-Com-vs2005] Как добраться до главного цикла программы
Отправлено: Разуев Максим от Ноябрь 12, 2007, 18:47
Проблема решилась лишь частично. Функцию (3D рендер библиотеки) я вызываю через таймер с нулевым временем(по assist-у это гарантируе вызов таймера при обработке каждого цикла сообщений.
Но при перемещении мышки между виджетом в котором выводится 3D-сцена и другой частью окна, происходим мигание сцены (вероятно перерисовка). При вызове диалога иногда изображение вообще пропадает.


Название: Re: [Qt 4.3.1-Win-Com-vs2005] Как добраться до главного цикла программы
Отправлено: Вячеслав от Ноябрь 12, 2007, 19:11
Проблема решилась лишь частично. Функцию (3D рендер библиотеки) я вызываю через таймер с нулевым временем(по assist-у это гарантируе вызов таймера при обработке каждого цикла сообщений.
Но при перемещении мышки между виджетом в котором выводится 3D-сцена и другой частью окна, происходим мигание сцены (вероятно перерисовка). При вызове диалога иногда изображение вообще пропадает.
НЕ правда Ваша ;)
Код:
As a special case, a QTimer with a timeout of 0 will time out as soon as all the events in the window system's event queue have been processed.
Когда нет больше сообщений в очереди IMHO ;)


Название: Re: [Qt 4.3.1-Win-Com-vs2005] Как добраться до главного цикла программы
Отправлено: pastor от Ноябрь 12, 2007, 19:18
Когда нет больше сообщений в очереди IMHO ;)

+1

Таймер с 0 таймаутом сработает когда в очереди обработки сообщений не будет событий (все будут обработаны). Т.е. другими словами, таймер срабатывать на "холостом ходу" цикла обработки сообщений