Ĺadny brzuch
Siemka. Mam do Was ogromna prosbe o pomoc. Prosze w miare mozliwosci zerknijcie na to i doradzcie. Chcialbym wyswietlac automatycznie w odstepach 10 sekundowych obrazki bmp, przed startem programu moze ich byc rozna ilosc a znajdowac sie beda w folderze powiedzmy 'obrazki' tam gdzie glowny program.
procedure Wyswietl; var tablicabmp : array of tbitmap; i:integer; begin setlength(tablicabmp,10); for i:=0 to high(tablicabmp) do begin tablicabmp[i] := tbitmap.create; tablicabmp[i].loadfromfile('C:\PLIKI\pliknr'+inttostr(i)+' .bmp'); end;
moje pytania
1) jak powinna wygladac ostatnia linijka by program wiedzial ze folder 'obrazki' znajduje sie tam gdzie cala aplikacja, bez wzgledu na to na jakim dysku to bedzie.
2) jak teraz dobrze odczytac z takiej tablicy do TImage tak by obrazki wyswietlaly sie co 10 sekund pewnie musze uzyc TTimer i zmienic czas w interval tylko nie umiem sobie poradzic z kodem zeby to zgrac w calosc.
3) Czy tablica dynamiczna jest dobrym wyborem gdyz gdzies cos przeczytalem ze mozna nazwy plikow zapisac do StringList lecz to juz dlamnie czarna magia
Wybaczcie za takie pytania lecz jesli mozecie to pomozcie bede bardzo wdzieczny
Pozdrawiam
Primo: zamiast trzymać tablicę typu TBitmap, trzymaj tylko ścieżki do obrazków (array of string lub TStringList). Ładowanie będzie następować dopiero przed wczytaniem.
AD1: Służy do tego funkcja ExtractFilePath(). W tym przypadku:
var folder: string; begin folder := ExtractFilePath(Application.Exexname) + 'obrazki\';
Ad2:
Może być i Timer. Interval na 10000, do tego zmienna globalna:
X: byte;
i w OnTimer:
Image1.Picture.LoadFromFile(tablica[X]); Inc(X);
Pamiętaj o obsłużeniu warunków, gdy X = ostatni element tablicy.
AD3: Już pisałem na początku.
Siemka. Mam do Was ogromna prosbe o pomoc. Prosze w miare mozliwosci zerknijcie na to i doradzcie. Chcialbym wyswietlac automatycznie w odstepach 10 sekundowych obrazki bmp, przed startem programu moze ich byc rozna ilosc a znajdowac sie beda w folderze powiedzmy 'obrazki' tam gdzie glowny program.
procedure Wyswietl; var tablicabmp : array of tbitmap; i:integer; begin setlength(tablicabmp,10); for i:=0 to high(tablicabmp) do begin tablicabmp[i] := tbitmap.create; tablicabmp[i].loadfromfile('C:\PLIKI\pliknr'+inttostr(i)+' .bmp'); end;
moje pytania
1) jak powinna wygladac ostatnia linijka by program wiedzial ze folder 'obrazki' znajduje sie tam gdzie cala aplikacja, bez wzgledu na to na jakim dysku to bedzie.
2) jak teraz dobrze odczytac z takiej tablicy do TImage tak by obrazki wyswietlaly sie co 10 sekund pewnie musze uzyc TTimer i zmienic czas w interval tylko nie umiem sobie poradzic z kodem zeby to zgrac w calosc.
3) Czy tablica dynamiczna jest dobrym wyborem gdyz gdzies cos przeczytalem ze mozna nazwy plikow zapisac do StringList lecz to juz dlamnie czarna magia
Wybaczcie za takie pytania lecz jesli mozecie to pomozcie bede bardzo wdzieczny
Pozdrawiam
ad1: ExtractFilePath(Application.ExeName)+'jakis_katalog\plik.bmp'
ad2: Nie musisz uzyć timerka. możesz dac; sleep(10000); To spowoduje zatrzymanie następnych linijek kodu na 10 sekund.
ad3. każde rozwiązanie jest dobre, które osiągnie zamierzony efekt i zajmie jaknajmniej pamięci
edit jak widać zostałem wyprzedzony
Użytkownik statjacek edytował ten post 13 lipiec 2007, 19:03
Co do pierwszego pytania to możesz zrobić tak jak doradzili ci statjacek i p... ale chyba możesz zrobić jeszcze w ten sposób:
tablicabmp[i].loadfromfile('obrazki\pliknr'+inttostr(i)+'.bmp' );
Użytkownik Capellini edytował ten post 13 lipiec 2007, 19:17
Ja w ogóle nie rozumiem po co te tablice :| Można by i bez nich zrobić stosując sam Timer i jedną zmienną (bądź nawet bez gdyby np. użyć Tag w TImage) :|
A tak w ogóle statjacek użyj sleep na 10 sek - nie dość, że aplikacja "zamarznie", to jeszcze nie będzie odbierać komunikatów od Windows'a, a co za tym idzie, jeżeli jakaś inna aplikacja przesłoni Image to będzie nieciekawy efekt :P W sleep się można bawić, ale w dodatkowych wątkach, a nie w wątku głównym programu.
//dopisane
Można jednak sobie z tym poradzić dając np fokusa za sleep na coś.
Głupotę napisałeś. Jak może się focus odpalić skoro aplikacja jest uśpiona? Przez te 10 sek nic nie poradzisz.
Użytkownik PcSA edytował ten post 13 lipiec 2007, 19:36
Ja w ogóle nie rozumiem po co te tablice :| Można by i bez nich zrobić stosując sam Timer i jedną zmienną (bądź nawet bez gdyby np. użyć Tag w TImage) :|
A tak w ogóle statjacek użyj sleep na 10 sek - nie dość, że aplikacja "zamarznie", to jeszcze nie będzie odbierać komunikatów od Windows'a, a co za tym idzie, jeżeli jakaś inna aplikacja przesłoni Image to będzie nieciekawy efekt :P W sleep się można bawić, ale w dodatkowych wątkach, a nie w wątku głównym programu.
To prawda co piszesz, ale jest to jakas zawsze alternatywa. Można jednak sobie z tym poradzić dając np fokusa za sleep na coś.
Chyba najlepsze rozwiazanie to timerek + petelka for. I na upartego to też wystarczy
Użytkownik statjacek edytował ten post 13 lipiec 2007, 19:35
To prawda co piszesz, ale jest to jakas zawsze alternatywa. Można jednak sobie z tym poradzić dając np fokusa za sleep na coś.
Chyba najlepsze rozwiazanie to timerek + petelka for. I na upartego to też wystarczy
For? A nie przypadkiem index ogólnie dostępny i w timerze
pokaz obrazka ('sciezka'+inttostr(jakisindex)+'.bmp'); inc(jakisindex);?
Dziekuje przedewszystkim za podpowiedzi.
A co sadzicie o tym i co byscie zmienili na lepsze, jak to powinno prosciej wygladac
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) Timer1: TTimer; procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Timer1Timer(Sender: TObject); procedure FormPaint(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; SciezkaExe:String; ListaBitmapek: array of TBitmap; ListaNazw :TStringList; I,Wsk:Integer; implementation {$R *.dfm} procedure FindBmp(Lista :TStringList;Path:String); var SearchResult : TSearchRec; begin if FindFirst(Path+'*.bmp', faAnyFile, SearchResult) = 0 then begin repeat Lista.Add(SearchResult.Name); until FindNext(SearchResult) <> 0; FindClose(searchResult); end; end; procedure TForm1.FormCreate(Sender: TObject); begin SciezkaExe:=ExtractFilePath(Application.ExeName); ListaNazw:=TStringList.Create; FindBmp(ListaNazw,SciezkaExe+'Obrazki\'); SetLength(ListaBitmapek,ListaNazw.Count); for I:= 0 to High(ListaBitmapek) do begin ListaBitmapek[I]:=TBitmap.Create; ListaBitmapek[I].LoadFromFile(SciezkaExe+'Obrazki\'+ListaNazw.Strings[i] ); end; ListaNazw.Free; end; procedure TForm1.Timer1Timer(Sender: TObject); begin if Length(ListaBitmapek)> 0 then begin Canvas.Rectangle(-1,-1,Width+1,Height+1); // zmazanie tego co pod spodem Canvas.Draw(0,0,ListaBitmapek[Wsk]); if Wsk< High(ListaBitmapek) then Inc(Wsk) else if Wsk = High(ListaBitmapek) then Wsk:=0; end else Timer1.Enabled :=False; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin for i:= 0 to High(ListaBitmapek) do ListaBitmapek[i].Free; end; procedure TForm1.FormPaint(Sender: TObject); begin Canvas.Rectangle(-1,-1,Width+1,Height+1); Canvas.Draw(0,0,ListaBitmapek[Wsk]); end; end.
Dziekuje przedewszystkim za podpowiedzi.
A co sadzicie o tym i co byscie zmienili na lepsze, jak to powinno prosciej wygladac
Po pierwsze bym wprowadził poprawne wcięcia.
var Form1: TForm1; SciezkaExe:String; ListaBitmapek: array of TBitmap; ListaNazw :TStringList; I,Wsk:Integer;
To bym dał w obrębie formy.
for I:= 0 to High(ListaBitmapek) do begin ListaBitmapek[I]:=TBitmap.Create; ListaBitmapek[I].LoadFromFile(SciezkaExe+'Obrazki\'+ListaNazw.Strings[i] ); end;
można wiedzieć po co Ci wszystkie bitmapy w pamięci? No chyba że masz jakiś hiperkrótki czas w timerze, ale zdaje się że była mowa o 10s.
Canvas.Rectangle(-1,-1,Width+1,Height+1); // zmazanie tego co pod spodem Canvas.Draw(0,0,ListaBitmapek[Wsk]);
ustaw pena i brusha i maluj na obszarze 0,0,width,height
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin for i:= 0 to High(ListaBitmapek) do ListaBitmapek[i].Free; end;
Jeszcze setlength na 0 dla listy (delphi sam powinien o to zadbać, ale dobrze jest jednak o takich rzeczach pamiętać).
procedure TForm1.FormPaint(Sender: TObject); begin Canvas.Rectangle(-1,-1,Width+1,Height+1); Canvas.Draw(0,0,ListaBitmapek[Wsk]); end;
Jak w timmerze. Poza tym - jeżeli masz to to czemu w timmerze nie zrobisz Form1.Repaint(); ?
Zastanów się dobrze czy warto marnować pamięć ram na trzymanie wszystkich obrazków w niej.
// Edit: I popraw na CODEBOX'a...
Użytkownik Ali240 edytował ten post 14 lipiec 2007, 07:34
Jejku dziekuje Wam za pomoc jest tego troche, szczerze to mam teraz metlik w glowie, wszystko do poprawy, no nic takie sa poczatki, bede dozgonnie wdzieczny jak pomozecie mi to poprawic bo nie wiem juz jak to zrobic, moja koncepcja padla w gruzach, siedze nadtym ale nic mi nie wychodzi :-(
Jejku dziekuje Wam za pomoc jest tego troche, szczerze to mam teraz metlik w glowie, wszystko do poprawy, no nic takie sa poczatki, bede dozgonnie wdzieczny jak pomozecie mi to poprawic bo nie wiem juz jak to zrobic, moja koncepcja padla w gruzach, siedze nadtym ale nic mi nie wychodzi :-(
Nie wiem jak inni, ale ja gotowego rozwiązania nie mam zamiaru dać. Jak czegoś nie wiesz to pytaj konkretnie, a na pewno ktoś podpowie.
No to wiec pytam :-)
var Form1: TForm1; SciezkaExe:String; ListaBitmapek: array of TBitmap; ListaNazw :TStringList; I,Wsk:Integer; To bym dał w obrębie formy.
Chodzi o sekcje private? 'TForm2 = class(TForm)' Czy tak?
a ote dwie rzeczy ponizej jesli mozna bym prosil o glebsze informacje, szczegolnie o to pierwsze bo za to naprawde nie wiem jak sie zabrac
for I:= 0 to High(ListaBitmapek) do begin ListaBitmapek[I]:=TBitmap.Create; ListaBitmapek[I].LoadFromFile(SciezkaExe+'Obrazki\'+ListaNazw.Strings[i] ); end; można wiedzieć po co Ci wszystkie bitmapy w pamięci? No chyba że masz jakiś hiperkrótki czas w timerze, ale zdaje się że była mowa o 10s. Canvas.Rectangle(-1,-1,Width+1,Height+1); // zmazanie tego co pod spodem Canvas.Draw(0,0,ListaBitmapek[Wsk]); ustaw pena i brusha i maluj na obszarze 0,0,width,height
canvas.pen i canvas.brush -> poczytaj jak również o rectangle.
Private lub public - w tym wypadku nie robi różnicy bo wszystko odczytujesz z wewnątrz obiektu.
a ote dwie rzeczy ponizej jesli mozna bym prosil o glebsze informacje, szczegolnie o to pierwsze bo za to naprawde nie wiem jak sie zabrac
Pytałem po co od razu ładujesz wszystkie obrazki do tablicy (co za tym idzie - zapychasz ram)? Nie lepiej obrazek wczytać bezpośrednio przed jego wyświetleniem (zakładając że to nie jest jakiś ogromny obraz, wczytywanie w czasie rzeczywistym nie będzie odczuwalne dla usera).
Pytałem po co od razu ładujesz wszystkie obrazki do tablicy (co za tym idzie - zapychasz ram)? Nie lepiej obrazek wczytać bezpośrednio przed jego wyświetleniem (zakładając że to nie jest jakiś ogromny obraz, wczytywanie w czasie rzeczywistym nie będzie odczuwalne dla usera).
Czy oto chodzilo?
var Form1: TForm1; SciezkaExe:String; Bitmapka: TBitmap; ListaNazw :TStringList; I,Wsk:Integer; implementation {$R *.dfm} {Timer1.Interval ustawiony na 2 000 ms (10s)} procedure FindBmp(Lista :TStringList;Path:String); var SearchResult : TSearchRec; begin if FindFirst(Path+'*.bmp', faAnyFile, SearchResult) = 0 then begin repeat Lista.Add(SearchResult.Name); until FindNext(SearchResult) <> 0; FindClose(searchResult); end; end; procedure TForm1.FormCreate(Sender: TObject); begin Bitmapka:=Tbitmap.Create; Canvas.Brush.Color :=clblack; // Kolor Tła formy SciezkaExe:=ExtractFilePath(Application.ExeName); //pobranie sciezki Exe'ca ListaNazw:=TStringList.Create; FindBmp(ListaNazw,SciezkaExe+'Obrazki\'); // wyszukanie nazw Bitmapek end; procedure TForm1.Timer1Timer(Sender: TObject); begin if ListaNazw.Count>0 then begin Canvas.Rectangle(-1,-1,Width+1,Height+1); // zmazanie tego co pod spodem Bitmapka.LoadFromFile(SciezkaExe+'Obrazki\'+ListaNazw[WSK]); Canvas.Draw(0,0,Bitmapka); if Wsk< ListaNazw.Count -1 then Inc(Wsk) else if Wsk =ListaNazw.Count -1 then Wsk:=0; end else Timer1.Enabled :=False; // Jak nie ma rysunków wylaczam timer'a end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin ListaNazw.Free; // zwolnienie Nazw Bitmapka.Free; // Zwolnienie na koniec pracy programu end; procedure TForm1.FormPaint(Sender: TObject); begin Canvas.Rectangle(-1,-1,Width+1,Height+1); // zmazanie tego co pod spodem Canvas.Draw(0,0,Bitmapka); end; end.
Czy oto chodzilo?
Tak, teraz już lepiej to wygląda.
{Timer1.Interval ustawiony na 2 000 ms (10s)} -> ja tu widze 2 sekundy, a nie 10 Oo.
Nadal trzymasz zmienne globalnie - no ale to już prywatny wybór.
I żeby usprawnić trochę (i zapobiec wpadką ;)), przed malowaniem ustaw brusha i pena (o czym już pisałem) i maluj tak jak pisałem. No i jak pisałem - zamiast dublować kod w timerze wywołuj From1.Repain();...
Szkoda, że trzeba się powtarzać :(.
Wybacz,nie powtarzasz sie chodzilo mi tylko o zerkniecie na ladowanie bitmapek,dlatego wlasnie zamiescilem tylko ten cytat.
Co do rad jesli chodzi o zmienne to tak posluchalem Cie lecz dla zamieszczenia tego tutaj zostawilem je globalnie by reszty kodu juz nie wklejac co do interval to literowka :-) przepraszam
Mam prosbe jesli chodzi o brusha i pena moge prosic cos wiecej na ten temat, moze inaczej - co masz na mysli ustaw dokladniej jeszcze co? - jeszcze wszystkiego odrazu niepotrafie pojac, przewidziec, zrozumiec
i Jesli moglbys pomuc troszke bardziej from1.repain()
Tak czy owak juz Bardzo Dziekuje za poswiecony czas i dobre rady
Wybacz,nie powtarzasz sie chodzilo mi tylko o zerkniecie na ladowanie bitmapek,dlatego wlasnie zamiescilem tylko ten cytat.
Co do rad jesli chodzi o zmienne to tak posluchalem Cie lecz dla zamieszczenia tego tutaj zostawilem je globalnie by reszty kodu juz nie wklejac co do interval to literowka :-) przepraszam
A to sorki, myślałem że olałeś.
Mam prosbe jesli chodzi o brusha i pena moge prosic cos wiecej na ten temat, moze inaczej - co masz na mysli ustaw dokladniej jeszcze co? - jeszcze wszystkiego odrazu niepotrafie pojac, przewidziec, zrozumiec Teraz wykorzystujesz domyślne ustawienia. Niby nie jest źle, ale jak np. będziesz potem chciał coś jeszcze dorysować etc. i zmienisz ustawienia brush'a i pen'a to przy "czyszczeniu" formy będą one takie jak je ustawisz w dowolnym miejscu. Także jest dobrze przestawić sobie brush.style na bssingle no i pena na pssingle (piszę z pamięci więc nazwy mogą się różnić). No i kolory zmienić na takie jakich tam używasz. Do tego rozmiar pena na 1 i możesz już malować nie wychodząc poza wymiary płutna (teraz malujesz po jednym px poza z każdej strony). Niby teraz działa, ale ja tam zawsze stosuję zasadę, że jak już coś robić to robić porządnie ;).
i Jesli moglbys pomuc troszke bardziej from1.repaint()
Jeżeli dobrze pamiętam to tak się nazywa procedura wymuszająca przemalowanie formy (wywołuje onpaint). Jeśli nie to jakoś inaczej, ale na pewno coś takiego jest ;). Skoro w timerze masz to samo co w onpaint to zamiast dublować kod, wystarczy wymusić przemalowanie formy.
Tak czy owak juz Bardzo Dziekuje za poswiecony czas i dobre rady
Proszę bardzo :).
zanotowane.pl doc.pisz.pl pdf.pisz.pl zsf.htw.pl
procedure Wyswietl; var tablicabmp : array of tbitmap; i:integer; begin setlength(tablicabmp,10); for i:=0 to high(tablicabmp) do begin tablicabmp[i] := tbitmap.create; tablicabmp[i].loadfromfile('C:\PLIKI\pliknr'+inttostr(i)+' .bmp'); end;
moje pytania
1) jak powinna wygladac ostatnia linijka by program wiedzial ze folder 'obrazki' znajduje sie tam gdzie cala aplikacja, bez wzgledu na to na jakim dysku to bedzie.
2) jak teraz dobrze odczytac z takiej tablicy do TImage tak by obrazki wyswietlaly sie co 10 sekund pewnie musze uzyc TTimer i zmienic czas w interval tylko nie umiem sobie poradzic z kodem zeby to zgrac w calosc.
3) Czy tablica dynamiczna jest dobrym wyborem gdyz gdzies cos przeczytalem ze mozna nazwy plikow zapisac do StringList lecz to juz dlamnie czarna magia
Wybaczcie za takie pytania lecz jesli mozecie to pomozcie bede bardzo wdzieczny
Pozdrawiam
Primo: zamiast trzymać tablicę typu TBitmap, trzymaj tylko ścieżki do obrazków (array of string lub TStringList). Ładowanie będzie następować dopiero przed wczytaniem.
AD1: Służy do tego funkcja ExtractFilePath(). W tym przypadku:
var folder: string; begin folder := ExtractFilePath(Application.Exexname) + 'obrazki\';
Ad2:
Może być i Timer. Interval na 10000, do tego zmienna globalna:
X: byte;
i w OnTimer:
Image1.Picture.LoadFromFile(tablica[X]); Inc(X);
Pamiętaj o obsłużeniu warunków, gdy X = ostatni element tablicy.
AD3: Już pisałem na początku.
Siemka. Mam do Was ogromna prosbe o pomoc. Prosze w miare mozliwosci zerknijcie na to i doradzcie. Chcialbym wyswietlac automatycznie w odstepach 10 sekundowych obrazki bmp, przed startem programu moze ich byc rozna ilosc a znajdowac sie beda w folderze powiedzmy 'obrazki' tam gdzie glowny program.
procedure Wyswietl; var tablicabmp : array of tbitmap; i:integer; begin setlength(tablicabmp,10); for i:=0 to high(tablicabmp) do begin tablicabmp[i] := tbitmap.create; tablicabmp[i].loadfromfile('C:\PLIKI\pliknr'+inttostr(i)+' .bmp'); end;
moje pytania
1) jak powinna wygladac ostatnia linijka by program wiedzial ze folder 'obrazki' znajduje sie tam gdzie cala aplikacja, bez wzgledu na to na jakim dysku to bedzie.
2) jak teraz dobrze odczytac z takiej tablicy do TImage tak by obrazki wyswietlaly sie co 10 sekund pewnie musze uzyc TTimer i zmienic czas w interval tylko nie umiem sobie poradzic z kodem zeby to zgrac w calosc.
3) Czy tablica dynamiczna jest dobrym wyborem gdyz gdzies cos przeczytalem ze mozna nazwy plikow zapisac do StringList lecz to juz dlamnie czarna magia
Wybaczcie za takie pytania lecz jesli mozecie to pomozcie bede bardzo wdzieczny
Pozdrawiam
ad1: ExtractFilePath(Application.ExeName)+'jakis_katalog\plik.bmp'
ad2: Nie musisz uzyć timerka. możesz dac; sleep(10000); To spowoduje zatrzymanie następnych linijek kodu na 10 sekund.
ad3. każde rozwiązanie jest dobre, które osiągnie zamierzony efekt i zajmie jaknajmniej pamięci
edit jak widać zostałem wyprzedzony
Użytkownik statjacek edytował ten post 13 lipiec 2007, 19:03
Co do pierwszego pytania to możesz zrobić tak jak doradzili ci statjacek i p... ale chyba możesz zrobić jeszcze w ten sposób:
tablicabmp[i].loadfromfile('obrazki\pliknr'+inttostr(i)+'.bmp' );
Użytkownik Capellini edytował ten post 13 lipiec 2007, 19:17
Ja w ogóle nie rozumiem po co te tablice :| Można by i bez nich zrobić stosując sam Timer i jedną zmienną (bądź nawet bez gdyby np. użyć Tag w TImage) :|
A tak w ogóle statjacek użyj sleep na 10 sek - nie dość, że aplikacja "zamarznie", to jeszcze nie będzie odbierać komunikatów od Windows'a, a co za tym idzie, jeżeli jakaś inna aplikacja przesłoni Image to będzie nieciekawy efekt :P W sleep się można bawić, ale w dodatkowych wątkach, a nie w wątku głównym programu.
//dopisane
Można jednak sobie z tym poradzić dając np fokusa za sleep na coś.
Głupotę napisałeś. Jak może się focus odpalić skoro aplikacja jest uśpiona? Przez te 10 sek nic nie poradzisz.
Użytkownik PcSA edytował ten post 13 lipiec 2007, 19:36
Ja w ogóle nie rozumiem po co te tablice :| Można by i bez nich zrobić stosując sam Timer i jedną zmienną (bądź nawet bez gdyby np. użyć Tag w TImage) :|
A tak w ogóle statjacek użyj sleep na 10 sek - nie dość, że aplikacja "zamarznie", to jeszcze nie będzie odbierać komunikatów od Windows'a, a co za tym idzie, jeżeli jakaś inna aplikacja przesłoni Image to będzie nieciekawy efekt :P W sleep się można bawić, ale w dodatkowych wątkach, a nie w wątku głównym programu.
To prawda co piszesz, ale jest to jakas zawsze alternatywa. Można jednak sobie z tym poradzić dając np fokusa za sleep na coś.
Chyba najlepsze rozwiazanie to timerek + petelka for. I na upartego to też wystarczy
Użytkownik statjacek edytował ten post 13 lipiec 2007, 19:35
To prawda co piszesz, ale jest to jakas zawsze alternatywa. Można jednak sobie z tym poradzić dając np fokusa za sleep na coś.
Chyba najlepsze rozwiazanie to timerek + petelka for. I na upartego to też wystarczy
For? A nie przypadkiem index ogólnie dostępny i w timerze
pokaz obrazka ('sciezka'+inttostr(jakisindex)+'.bmp'); inc(jakisindex);?
Dziekuje przedewszystkim za podpowiedzi.
A co sadzicie o tym i co byscie zmienili na lepsze, jak to powinno prosciej wygladac
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) Timer1: TTimer; procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Timer1Timer(Sender: TObject); procedure FormPaint(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; SciezkaExe:String; ListaBitmapek: array of TBitmap; ListaNazw :TStringList; I,Wsk:Integer; implementation {$R *.dfm} procedure FindBmp(Lista :TStringList;Path:String); var SearchResult : TSearchRec; begin if FindFirst(Path+'*.bmp', faAnyFile, SearchResult) = 0 then begin repeat Lista.Add(SearchResult.Name); until FindNext(SearchResult) <> 0; FindClose(searchResult); end; end; procedure TForm1.FormCreate(Sender: TObject); begin SciezkaExe:=ExtractFilePath(Application.ExeName); ListaNazw:=TStringList.Create; FindBmp(ListaNazw,SciezkaExe+'Obrazki\'); SetLength(ListaBitmapek,ListaNazw.Count); for I:= 0 to High(ListaBitmapek) do begin ListaBitmapek[I]:=TBitmap.Create; ListaBitmapek[I].LoadFromFile(SciezkaExe+'Obrazki\'+ListaNazw.Strings[i] ); end; ListaNazw.Free; end; procedure TForm1.Timer1Timer(Sender: TObject); begin if Length(ListaBitmapek)> 0 then begin Canvas.Rectangle(-1,-1,Width+1,Height+1); // zmazanie tego co pod spodem Canvas.Draw(0,0,ListaBitmapek[Wsk]); if Wsk< High(ListaBitmapek) then Inc(Wsk) else if Wsk = High(ListaBitmapek) then Wsk:=0; end else Timer1.Enabled :=False; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin for i:= 0 to High(ListaBitmapek) do ListaBitmapek[i].Free; end; procedure TForm1.FormPaint(Sender: TObject); begin Canvas.Rectangle(-1,-1,Width+1,Height+1); Canvas.Draw(0,0,ListaBitmapek[Wsk]); end; end.
Dziekuje przedewszystkim za podpowiedzi.
A co sadzicie o tym i co byscie zmienili na lepsze, jak to powinno prosciej wygladac
Po pierwsze bym wprowadził poprawne wcięcia.
var Form1: TForm1; SciezkaExe:String; ListaBitmapek: array of TBitmap; ListaNazw :TStringList; I,Wsk:Integer;
To bym dał w obrębie formy.
for I:= 0 to High(ListaBitmapek) do begin ListaBitmapek[I]:=TBitmap.Create; ListaBitmapek[I].LoadFromFile(SciezkaExe+'Obrazki\'+ListaNazw.Strings[i] ); end;
można wiedzieć po co Ci wszystkie bitmapy w pamięci? No chyba że masz jakiś hiperkrótki czas w timerze, ale zdaje się że była mowa o 10s.
Canvas.Rectangle(-1,-1,Width+1,Height+1); // zmazanie tego co pod spodem Canvas.Draw(0,0,ListaBitmapek[Wsk]);
ustaw pena i brusha i maluj na obszarze 0,0,width,height
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin for i:= 0 to High(ListaBitmapek) do ListaBitmapek[i].Free; end;
Jeszcze setlength na 0 dla listy (delphi sam powinien o to zadbać, ale dobrze jest jednak o takich rzeczach pamiętać).
procedure TForm1.FormPaint(Sender: TObject); begin Canvas.Rectangle(-1,-1,Width+1,Height+1); Canvas.Draw(0,0,ListaBitmapek[Wsk]); end;
Jak w timmerze. Poza tym - jeżeli masz to to czemu w timmerze nie zrobisz Form1.Repaint(); ?
Zastanów się dobrze czy warto marnować pamięć ram na trzymanie wszystkich obrazków w niej.
// Edit: I popraw na CODEBOX'a...
Użytkownik Ali240 edytował ten post 14 lipiec 2007, 07:34
Jejku dziekuje Wam za pomoc jest tego troche, szczerze to mam teraz metlik w glowie, wszystko do poprawy, no nic takie sa poczatki, bede dozgonnie wdzieczny jak pomozecie mi to poprawic bo nie wiem juz jak to zrobic, moja koncepcja padla w gruzach, siedze nadtym ale nic mi nie wychodzi :-(
Jejku dziekuje Wam za pomoc jest tego troche, szczerze to mam teraz metlik w glowie, wszystko do poprawy, no nic takie sa poczatki, bede dozgonnie wdzieczny jak pomozecie mi to poprawic bo nie wiem juz jak to zrobic, moja koncepcja padla w gruzach, siedze nadtym ale nic mi nie wychodzi :-(
Nie wiem jak inni, ale ja gotowego rozwiązania nie mam zamiaru dać. Jak czegoś nie wiesz to pytaj konkretnie, a na pewno ktoś podpowie.
No to wiec pytam :-)
var Form1: TForm1; SciezkaExe:String; ListaBitmapek: array of TBitmap; ListaNazw :TStringList; I,Wsk:Integer; To bym dał w obrębie formy.
Chodzi o sekcje private? 'TForm2 = class(TForm)' Czy tak?
a ote dwie rzeczy ponizej jesli mozna bym prosil o glebsze informacje, szczegolnie o to pierwsze bo za to naprawde nie wiem jak sie zabrac
for I:= 0 to High(ListaBitmapek) do begin ListaBitmapek[I]:=TBitmap.Create; ListaBitmapek[I].LoadFromFile(SciezkaExe+'Obrazki\'+ListaNazw.Strings[i] ); end; można wiedzieć po co Ci wszystkie bitmapy w pamięci? No chyba że masz jakiś hiperkrótki czas w timerze, ale zdaje się że była mowa o 10s. Canvas.Rectangle(-1,-1,Width+1,Height+1); // zmazanie tego co pod spodem Canvas.Draw(0,0,ListaBitmapek[Wsk]); ustaw pena i brusha i maluj na obszarze 0,0,width,height
canvas.pen i canvas.brush -> poczytaj jak również o rectangle.
Private lub public - w tym wypadku nie robi różnicy bo wszystko odczytujesz z wewnątrz obiektu.
a ote dwie rzeczy ponizej jesli mozna bym prosil o glebsze informacje, szczegolnie o to pierwsze bo za to naprawde nie wiem jak sie zabrac
Pytałem po co od razu ładujesz wszystkie obrazki do tablicy (co za tym idzie - zapychasz ram)? Nie lepiej obrazek wczytać bezpośrednio przed jego wyświetleniem (zakładając że to nie jest jakiś ogromny obraz, wczytywanie w czasie rzeczywistym nie będzie odczuwalne dla usera).
Pytałem po co od razu ładujesz wszystkie obrazki do tablicy (co za tym idzie - zapychasz ram)? Nie lepiej obrazek wczytać bezpośrednio przed jego wyświetleniem (zakładając że to nie jest jakiś ogromny obraz, wczytywanie w czasie rzeczywistym nie będzie odczuwalne dla usera).
Czy oto chodzilo?
var Form1: TForm1; SciezkaExe:String; Bitmapka: TBitmap; ListaNazw :TStringList; I,Wsk:Integer; implementation {$R *.dfm} {Timer1.Interval ustawiony na 2 000 ms (10s)} procedure FindBmp(Lista :TStringList;Path:String); var SearchResult : TSearchRec; begin if FindFirst(Path+'*.bmp', faAnyFile, SearchResult) = 0 then begin repeat Lista.Add(SearchResult.Name); until FindNext(SearchResult) <> 0; FindClose(searchResult); end; end; procedure TForm1.FormCreate(Sender: TObject); begin Bitmapka:=Tbitmap.Create; Canvas.Brush.Color :=clblack; // Kolor Tła formy SciezkaExe:=ExtractFilePath(Application.ExeName); //pobranie sciezki Exe'ca ListaNazw:=TStringList.Create; FindBmp(ListaNazw,SciezkaExe+'Obrazki\'); // wyszukanie nazw Bitmapek end; procedure TForm1.Timer1Timer(Sender: TObject); begin if ListaNazw.Count>0 then begin Canvas.Rectangle(-1,-1,Width+1,Height+1); // zmazanie tego co pod spodem Bitmapka.LoadFromFile(SciezkaExe+'Obrazki\'+ListaNazw[WSK]); Canvas.Draw(0,0,Bitmapka); if Wsk< ListaNazw.Count -1 then Inc(Wsk) else if Wsk =ListaNazw.Count -1 then Wsk:=0; end else Timer1.Enabled :=False; // Jak nie ma rysunków wylaczam timer'a end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin ListaNazw.Free; // zwolnienie Nazw Bitmapka.Free; // Zwolnienie na koniec pracy programu end; procedure TForm1.FormPaint(Sender: TObject); begin Canvas.Rectangle(-1,-1,Width+1,Height+1); // zmazanie tego co pod spodem Canvas.Draw(0,0,Bitmapka); end; end.
Czy oto chodzilo?
Tak, teraz już lepiej to wygląda.
{Timer1.Interval ustawiony na 2 000 ms (10s)} -> ja tu widze 2 sekundy, a nie 10 Oo.
Nadal trzymasz zmienne globalnie - no ale to już prywatny wybór.
I żeby usprawnić trochę (i zapobiec wpadką ;)), przed malowaniem ustaw brusha i pena (o czym już pisałem) i maluj tak jak pisałem. No i jak pisałem - zamiast dublować kod w timerze wywołuj From1.Repain();...
Szkoda, że trzeba się powtarzać :(.
Wybacz,nie powtarzasz sie chodzilo mi tylko o zerkniecie na ladowanie bitmapek,dlatego wlasnie zamiescilem tylko ten cytat.
Co do rad jesli chodzi o zmienne to tak posluchalem Cie lecz dla zamieszczenia tego tutaj zostawilem je globalnie by reszty kodu juz nie wklejac co do interval to literowka :-) przepraszam
Mam prosbe jesli chodzi o brusha i pena moge prosic cos wiecej na ten temat, moze inaczej - co masz na mysli ustaw dokladniej jeszcze co? - jeszcze wszystkiego odrazu niepotrafie pojac, przewidziec, zrozumiec
i Jesli moglbys pomuc troszke bardziej from1.repain()
Tak czy owak juz Bardzo Dziekuje za poswiecony czas i dobre rady
Wybacz,nie powtarzasz sie chodzilo mi tylko o zerkniecie na ladowanie bitmapek,dlatego wlasnie zamiescilem tylko ten cytat.
Co do rad jesli chodzi o zmienne to tak posluchalem Cie lecz dla zamieszczenia tego tutaj zostawilem je globalnie by reszty kodu juz nie wklejac co do interval to literowka :-) przepraszam
A to sorki, myślałem że olałeś.
Mam prosbe jesli chodzi o brusha i pena moge prosic cos wiecej na ten temat, moze inaczej - co masz na mysli ustaw dokladniej jeszcze co? - jeszcze wszystkiego odrazu niepotrafie pojac, przewidziec, zrozumiec Teraz wykorzystujesz domyślne ustawienia. Niby nie jest źle, ale jak np. będziesz potem chciał coś jeszcze dorysować etc. i zmienisz ustawienia brush'a i pen'a to przy "czyszczeniu" formy będą one takie jak je ustawisz w dowolnym miejscu. Także jest dobrze przestawić sobie brush.style na bssingle no i pena na pssingle (piszę z pamięci więc nazwy mogą się różnić). No i kolory zmienić na takie jakich tam używasz. Do tego rozmiar pena na 1 i możesz już malować nie wychodząc poza wymiary płutna (teraz malujesz po jednym px poza z każdej strony). Niby teraz działa, ale ja tam zawsze stosuję zasadę, że jak już coś robić to robić porządnie ;).
i Jesli moglbys pomuc troszke bardziej from1.repaint()
Jeżeli dobrze pamiętam to tak się nazywa procedura wymuszająca przemalowanie formy (wywołuje onpaint). Jeśli nie to jakoś inaczej, ale na pewno coś takiego jest ;). Skoro w timerze masz to samo co w onpaint to zamiast dublować kod, wystarczy wymusić przemalowanie formy.
Tak czy owak juz Bardzo Dziekuje za poswiecony czas i dobre rady
Proszę bardzo :).