Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.68/50: Рейтинг темы: голосов - 50, средняя оценка - 4.68
 Аватар для Jafa
51 / 51 / 13
Регистрация: 05.06.2008
Сообщений: 139

Анимация ожидания

17.05.2010, 01:04. Показов 10814. Ответов 30
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
У меня в приложении есть длительные процессы, например подключение к удаленной базе данных, обычно в таких случаях я вывожу надпись типа "ждите", в этот раз я решил вывести gif-анимацию в TImage, но она во время выполнения процесса останавливается, пробовал играться с дочерним процессом - тоже не помогло, может кто подскажет как ее оживить во время выполнения процесса?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.05.2010, 01:04
Ответы с готовыми решениями:

Потоки и таймеры ожидания
Есть вот такая задача: Пользователь задает список, каждый элемент которого включает дату и время. Количество (пар дата / время) не...

Задать время ожидания на чтение файла
Требуется прочитать текстовый файл и преобразовать его TStringList. Обычно я это делаю одной...

Анимация ожидания
Здравствуйте! В приложении работаю с Picasso, на загрузке стоит заглушка ,можно поменять png на gif? Если да, то как? При прямолобной...

30
Эксперт С++
 Аватар для MikeSoft
3957 / 1812 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
04.02.2011, 01:00
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Evg Посмотреть сообщение
"Недействительная" - имелось в виду то, что текущее графическое изображение недействительно?
Да. Объявляется недействительной вся клиентская область.
Цитата Сообщение от Evg Посмотреть сообщение
Там была ссылка на тему со StringGrid'ом - по сути одна из модификаций этого самого. Только обновление (вызов RePaint, или как там оно) шёл из потока
Так в таких вызовах нет ничего плохого, насколько я что-то в чём-то понимаю...
В общем, будет время - посмотрю, что можно сотворить со StringGrid'ами в потоках...


Окей, завтра посмотрю второе приложение под Windows 7 и разберусь в чём же причины...
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
04.02.2011, 01:06
Цитата Сообщение от MikeSoft Посмотреть сообщение
Да. Объявляется недействительной вся клиентская область.
Так в таких вызовах нет ничего плохого, насколько я что-то в чём-то понимаю...
- MikeSoft , сказал бы на человеко-понятном языке - Invalidate() перерисовывает (обновляет) канву. Как-то так .
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
04.02.2011, 08:52
Цитата Сообщение от MikeSoft Посмотреть сообщение
Окей, завтра посмотрю второе приложение под Windows 7 и разберусь в чём же причины...
Да и с первым не всё в порядке. И сделай для порядку вариант без потоков (пусть и подтормаживающий). Хочется понять, причина в работе с канвой из потока или в чём-то другом
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
07.05.2013, 01:20
Попытался проанализировать код MikeSoft:

Писал по первым его исходникам в теме. ( но разница в коде не велика )
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//---------------------------------------------------------------------------
void __fastcall TProgressShow::Execute()
{
    // Далее обращение без синхронизации :
    TCanvas *Canvas = MainControl->ProgressImage->Canvas;
    int Width = MainControl->ProgressImage->Width;
    int Height = MainControl->ProgressImage->Height;
    Canvas->Font->Color = clWhite; //  Запись в разделяемый объект -
    Canvas->Font->Size = 14;        //  теоретически может быть опасным
                            //  зависит от внутренних механизмов VCL
 
    // MainControl->LoadPercent - тоже разделяемый ресурс
    // и тут вопрос атомарности операций с int
    // теоретически тут тоже могут быть проблемы
 
    while (MainControl->LoadPercent != 100)
      {
       //  Тут все вроде гладко :
       //  дают возможность - рисуем
       //  нет - "висим в цикле",
       //  но я не уверен в том что рационально "висеть в цикле"
       //  почему нельзя просто "замереть" в ожидании? ( Canvas->Lock() )
        if (Canvas->TryLock() )
          {
            DrawTestRect(Canvas,Width,Height);
            DrawText(Canvas,Width,Height,IntToStr(MainControl->LoadPercent) + "% Percent Complete...");
            // если в друг где-тут возникнет исключение
            // канвас не разблокируется,будет deadlock,
            // приложение успешнО упадЁт,
            // выход- используем try / __finally
            Canvas->Unlock(); 
          }
        //  Вероятен случай что нам просто не дали прорисовать
        //  последние значения LoadPercent и мы просто выйдем из цикла
        //  так и не прорисовав их.
 
        Sleep(50);
      }
 
    // Следующие ф-ции непотокобезопастны,
    // почему без синхронизации ?
    // - явно может привести к падению приложения :
    DrawTestRect(Canvas,Width,Height);
    DrawText(Canvas,Width,Height,"Task Was Completed.");
}
//---------------------------------------------------------------------------
Есть еще момент Invalidate() который делает перерисовку всего окна, затирая нарисованное потоком, что порой сильно заметно.
Кстати читал где-то недавно что якобы VCL не позволяет перерисовывать часть окна.

Стоит заметить что данный момент можно рассматривать как - следствие неправильного распределения задач :
логичнее за прорисовку назначить ответственным основной поток, а заполнение массива отдать потоку.
А то после завершения потока прорисовывать канву попросту некому.

Как вариант решения - использовать канву TImage которая "сохраняет в себе" нарисованное.

Если первый пример у меня работает более менее нормально, то второй явно работает как-то неправильно.





P.S. Предложение к администрации перенести часть обсуждения из Выход из обработчика onclick сюда как более соответствующие этой теме.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
07.05.2013, 10:33
Цитата Сообщение от Avazart Посмотреть сообщение
Стоит заметить что данный момент можно рассматривать как - следствие неправильного распределения задач :
логичнее за прорисовку назначить ответственным основной поток, а заполнение массива отдать потоку
Собственно, этот пример и делался как демонстрация того, что так делать необязательно, т.к. есть инструменты, которые позволяют рисовать в потоке. Обычная логика такому не противоречит. Противоречит этому техническая реализация VCL.
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
07.05.2013, 12:48
В борланде доступны четыре вида перерисовки большинства компонентов. Вот выдержка из "Освой самостоятельно борланду" Рейсдорфа и Хендерсона (с моим пониманием происходящего):

Invalidate - Запрашивает перерисовку компонента. Компонент будет перерисован Windows при первой возможности.
(Перекрашивает прям весь компонент сразу. (отправляет сообщение виндовсу, что неплохо было бы, когда тому будет удобно, обновить вот этот вот компонент) За один проход, избегая мерцания. То есть не перерисовывает по отдельности всякие рамочки, надписи, фон, рисуночки... Скорее всего действует как двойная буферизация, - сперва рисует в буфер, а потом уже сформированный буфер на форме.)
Refresh - Запрашивает немедленную перерисовку компонента, стирая перед этим изображение компонента.
(Возвращает компонент в первоначальное состояние. Не меняет кисть или шрифт. Берет предыдущее не закрепленное Invalidate-ом или Update-ом состояние и тупо его перерисовывает. Предварительно замазав цветом фона прямоугольник по размерам компонента.)
Repaint - Запрашивает немедленную перерисовку компонента. Стирание фона предварительно не производится.
(Если не установлено свойство csOpaque (прозрачности), то вызывает Invalidate, затем Update, что гарантирует перерисовку всего компонента, даже тех мест, которые в данный момент скрыты. Если свойство установлено, то только видимую часть.)
Update - Вызывает немедленную принудительную перерисовку компонента.
(Перерисовывает только те участки компонента, которые были изменены, но сейчас же, принудительно, не дожидаясь виндовой очереди.)


А вообще, господа, позвольте влезть к вам со своим монастырем:
хочу создать компонент с вычурным графиком, чтобы в реалтайме менялся каждые n секунд. Думал просто создать класс, прикрутить к нему TTimer, завернуть все это в компонент и потом набрасывать на форму миллион таких графиков. Соответственно будет миллион таймеров. А вот вы меня смутили. Все они будут отображаться в потоке главной формы, значит надо именно ему отдавать всю прорисовку. Считаются каждый сам по себе, а прорисовываются все в форме. Все верно?

Цитата Сообщение от Evg Посмотреть сообщение
Всякие TryLock и прочее - а внутри кодов VCL это делается или не делается?
Вот это кстати хотелось бы все таки узнать.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
07.05.2013, 13:51
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Соответственно будет миллион таймеров
Насколько я понимаю, компонент будет всё-таки не миллион, а десятки. Десятки таймеров с интервалом в N секунд - это довольно НЕнапряжно для программы.

Цитата Сообщение от SatanaXIII Посмотреть сообщение
Все они будут отображаться в потоке главной формы, значит надо именно ему отдавать всю прорисовку
Утверждается, что они могут отображаться в том числе и в потоке, нужно только правильно это сделать, но, насколько я понял, пока никто не готов стопроцентно ответить на вопрос "а как правильно в потоке перерисовать график"

Цитата Сообщение от SatanaXIII Посмотреть сообщение
Считаются каждый сам по себе, а прорисовываются все в форме. Все верно?
Пока мне интуитивно кажется, что такой вариант наиболее правильный. Хотя если разберутся, как это рисовать из потока, то можно логику программы поменять и рисовать из потока. Нона скорость отрисовки это точно никак не повлияет, т.к. делать расчёты в параллель можно, но прорисовка всё равно будет строго последовательная (потоки по очереди будут занимать ресурс)
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
07.05.2013, 14:29
Цитата Сообщение от Evg Посмотреть сообщение
Десятки таймеров с интервалом в N секунд - это довольно НЕнапряжно для программы.
Это я к тому, что не охота возиться с живыми потоками. Пусть VCL сама с собой разбирается.

Цитата Сообщение от Evg Посмотреть сообщение
Нона скорость отрисовки это точно никак не повлияет
Скорость то ладно, меня сейчас более интересует такой аспект, что может быть дерганая перерисовка нескольких графиков с разными шагами отрисовки.
  • Если рисовать из компонента, то таймер отработал - нарисовал, отработал - нарисовал..
  • А относительно формы получится что когда форма получает управление она всех перерисовывает, не взирая кто успел посчитаться, кто нет. И если шаг перерисовки формы не будет кратен шагу таймера графика, то он будет в определенные моменты либо пропускать один такт, либо, наоборот, запаздывать.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
07.05.2013, 15:06
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Это я к тому, что не охота возиться с живыми потоками. Пусть VCL сама с собой разбирается
Нужно, или не нужно создавать потоки, зависит исключительно от того, сколько времени делается рассчётная часть. Если рассчёты типа вычислить сумму двух чисел, то ради них не имеет смысла делать поток. Если рассчёт типа обработки матрицы миллион на миллион - то его однозначно выполнять в потоке, т.к. такой рассчёт будет долгим и если его делать в основном процессе, то форма стабильно будет замороженная

Цитата Сообщение от SatanaXIII Посмотреть сообщение
А относительно формы получится что когда форма получает управление она всех перерисовывает, не взирая кто успел посчитаться, кто нет
Что перерисовывает форма - зависит исключительно от того, как ты напишешь программу. Поскольку ты не говоришь о том, что за графики и что вообще за логика всего этого деяния, то тут сложно понять, что ты вообще имеешь в виду. Под с$анным линуксом у меня картинка не отображается в нормальном масштабе, а по превью я затрудняюсь понять, что там

Добавлено через 8 минут
Добрые люди извлекли картинку. Прямоугольниками подсвечен момент времени, когда форма получает сигнал от таймера и когда поток готов выдать данные? В этом случае однозначно надо организовывать сообщения. Поток посчитал данные, кинул сообщение главному процессу, главный процесс сообщение поймал, данные извлёк, на форму нарисовал. При таком раскладе таймер вообще не нужен
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
07.05.2013, 15:40
Цитата Сообщение от Evg Посмотреть сообщение
Собственно, этот пример и делался как демонстрация того, что так делать необязательно, т.к. есть инструменты, которые позволяют рисовать в потоке. Обычная логика такому не противоречит. Противоречит этому техническая реализация VCL.
Логике противоречит по тому что неважно какая либа и какие средства- от правильного проектирования никто не освобождал: одна задача- одна сущность. Иначе получаем кашу.
И VCL тут не причем абсолютно, в Qt к примером та же ситуация как я понимаю. Да и при чем тут VCL и Qt ? ведь все определяется WinApi.

В WinApi приложении есть оконная процедура в которой обрабатывается событие WM_PAINT котором и делается прорисовка. И что бы рисовать в этом окне из другого окна - придется так же делать синхронизацию так как GDI ф-ции рисования потокобезопастны.

То что пример- это лишь пример и так понятно.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.07.2014, 16:10
SatanaXIII,

Валерий Фаронов "Искусство создания компонентов Delphi" стр.75 :
Миниатюры
Анимация ожидания  
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.07.2014, 16:10
Помогаю со студенческими работами здесь

Анимация ожидания
Нужно заблокировать экран и вывести картинку ожидания, пока не выполнится некое действие

Анимация ожидания ответа запроса от сервера
Помогите ребят Нигде не могу найти как сделать анимацию Допустим я ввожу логин и пароль Нажимаю кнопку В то время пока запрос...

Анимация ожидания ответа ajax запроса
Можно ли сделать анимацию загрузки такую как на этом видео: тыЦ это анимация из samsung touchwiz android 5.0 Как сделать такую на...

Анимация ожидания Ajax ответа на кнопках
Добрый вечер форумчане. Захотелось сделать универсальную функцию: после нажатия на кнопку (ДАННУЮ), сменить его содержимое анимацией, а...

Анимация в OpenGL, а где собсно, анимация?
// Bounce.cpp // Demonstrates a simple animated rectangle program with GLUT // OpenGL SuperBible, 3rd Edition // Richard S. Wright...


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

Или воспользуйтесь поиском по форуму:
31
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru