Builder C++ Sleep

0

Witam
Mam parę Labeli, powiedzmy że 4, Caption odpowiednio 1,2,3,4. Chcę zrobić tak, aby zamiast 1 pojawiła się 4, poczekał 0.5s, zamiast 4 pojawiła się 1 itd, aż wszystkie cyfry się przestawią i będzie 4,3,2,1. Używałem do tego Sleep(500), ale działa to w ten sposób, że czeka 4x 500ms i w jednym momencie wyświetla wszystkie cyfry przestawione.

void __fastcall TForm2::Button1Click(TObject *Sender)
{
      Label1->Caption="4";
      Sleep(500);
      Label2->Caption="3";
      Sleep(500);
      Label3->Caption="2";
      Sleep(500);
      Label4->Caption="1";
}

Tak napisałem to w Builderze i nie działa. Jak zrobić aby po zmianie każdego Labela odczekiwało podany czas?

0

Problem jest taki że ta procedura i Sleep() działają na tym samym wątku co UI. Oznacza to, że aby zaktualizować zmianę tekstu program musi wyjść najpierw z procedury obsługi przycisku.

Idealnym rozwiązaniem byłoby stworzenie osobnego wątku dla opóźnień tak, aby UI mogło działać cały czas.

0

Radzę poczytać o Event Loop.
To właśnie tan następuje komunikacja z systemem i wywoływane są zarżenia powodujące odrysowanie widoków.
Twój kod nie zwraca kontroli do Event Loop-a, więc odrysowanie nie następuje dopóki twoja funkcja nie zakończy się wykonywać.

0

Moglibyście napisać jakby to miało wyglądać choć dla jednego Labela? Dopiero zaczynam i nie ukrywam, że jest to jeszcze dla mnie czarna magia a na przykładach uczyć się najlepiej :D

0

Albo dodaj Application->ProcessMessages(); po zmianie każdego Caption z wyjątkiem ostatniego.

0
git napisał(a):

Albo dodaj Application->ProcessMessages(); po zmianie każdego Caption z wyjątkiem ostatniego.

Beznadziejne rozwiązanie. Lepiej wywalić Sleep i użyć Timer-a, który będzie wywoływał zdarzenie w określonych odstępach czasu
Sleep to jest wielkie nieporozumienie i powinno się go unikać jak ognia, zawsze jeśli chodzi o wątek UI, dla innych wątków mogą być wyjątki od tej zasady (to dla tych co by chcieli flama zacząć na ten temat).

1 użytkowników online, w tym zalogowanych: 0, gości: 1