Jak stosować styl pbstMarquee w TProgressBar ?

0

Jaku użyć tego stylu ?
pbstNormal - tu są jakieś przykłady i podpowiedzi z edytora sugerują sposób - min,max,step, iteracja stepit, i na koniec max na 0 - z głowy.
A pbstMarquee nie wiem i nie mogę żadnego przykładu znaleźć :/.

1

pbstMarquee to styl przeznaczony dla paska animowanego, który nie określa postępu wykonanych zadań. Dzięki niemu pasek informuje swoim wyglądem użytkownika, że wykonywane są jakieś operacje, ale czas ich zakończenia nie jest znany. Tak więc wystarczy ten styl ustawić, a całą resztę odwali LCL.

W załączniku jest filmik demonstrujący działanie tej opcji pod WinXP.

0

Dzięki - mam to wszystko poustawiane i niby działa - ale tylko jak program nic nie robi :/.
To procedura która mnie interesuje :

procedure TCardRotate.Button1Click(Sender: TObject);
var
  zapMSA, zapPQ: string;
  strtemp: string;
  i, ilewiersz, ilewiersz2: integer;
  khem, id, cid, oid, dim, tim: string;
begin
  if podajplikbazy.FileName <> '' then
  begin

    pasekimport.Style := pbstMarquee;
    pasekimport.Min := 1;
    pasekimport.Max := 100;
    //--------------------------------- test ile wlasciwie jest rekordow do 'wciagniecia'
    MSATrans.Active := True;
    zapMSA :=
      'select count(*) as ilosc from EventRecord where EventType=1 and ctrlID=4 and EmployeeID>=0 ';
    MSAQuery.SQL.Text := zapMSA;
    MSADSource.DataSet := MSAQuery;
    MSADSource.DataSet.Active := True;
    MSADSource.DataSet.Refresh;
    ilewiersz2 := MSADSource.DataSet.FieldByName('ilosc').Value;
    MSAQuery.Clear;
    MSAQuery.Close;

    MSADSource.DataSet.Active := False;
    MSADSource.DataSet.Close;

    // --------------------------- tu nastepuje wlasciwy import

    pasekimport.Style := pbstNormal;
    pasekimport.Min := 1;
    pasekimport.Max := ilewiersz2;
    pasekimport.Step := 1;

    MSATrans.Active := True;
    zapMSA :='select EventType,EmployeeID,CtrlID,Ordinal,AriseTime,format(arisetime,''short date'') as sdata,format(arisetime,''long time'') as stime '+
      'from EventRecord where EventType=1 and ctrlID=4 and EmployeeID>=0  order by AriseTime';
    MSAQuery.SQL.Text := zapMSA;
    MSADSource.DataSet := MSAQuery;
    MSADSource.DataSet.Active := True;
    MSADSource.DataSet.Refresh;

    ilewiersz := MSADSource.DataSet.RecordCount;
    button1.Caption := 'Czekaj !';

    for i := 0 to ilewiersz - 1 do
    begin
      button1.Caption := 'Czekaj !';
      pasekimport.StepIt;
      id := IntToStr(MSADSource.DataSet.FieldByName('EmployeeID').Value);
      cid := IntToStr(MSADSource.DataSet.FieldByName('CtrlID').Value);
      oid := IntToStr(MSADSource.DataSet.FieldByName('Ordinal').Value);
      tim := FormatDateTime('hh:nn:ss', MSADSource.DataSet.FieldByName('stime').Value);
      dim := FormatDateTime('YYYY.MM.DD', MSADSource.DataSet.FieldByName('sdata').Value);
      khem := IntToStr(DateTimeToFileDate(
        MSADSource.DataSet.FieldByName('AriseTime').Value));
      strtemp := khem + id + cid + oid;
      zapPQ := 'INSERT INTO recorder.record (iduser,data,time,event,controlsum)  VALUES ('
        + id + ',''' + dim + ''',''' + tim + ''',' + oid + ',' + strtemp + ')  ON CONFLICT (controlsum) DO NOTHING';
      PQTrans.Active := False;
      PQuery.sql.Text := zapPQ;
      PQTrans.StartTransaction;
      PQuery.ExecSQL;
      PQTrans.Commit;
      PQuery.Clear;
      PQuery.Close;
      MSADSource.DataSet.Next;
    end;

    MSAQuery.Clear;
    MSAQuery.Close;
    MSADSource.DataSet.Active := False;
    MSADSource.DataSet.Close;
    button1.Caption := 'Import';
    pasekimport.Style := pbstNormal;
  end
  else
    ShowMessage('Nie wskazano pliku bazy do importu !!');
end;         

Ustawiam na początku pbstMarquee by polatało gdy jeszcze nie wiem ile rekordów będzie, następnie przechodzę na pbstNormal gdy już to wiem.
I druga część działa spoko, pierwsza jakby robi tylko jeden krok.
Nie wiem również dlaczego w trakcie całej tej procedury okno aplikacji "zamarza" - nie daje się go przesunąć - przy 2-3 takich próbach wyskakuje "(brak odpowiedzi)" przy tytule i tak zostaje aż do momentu gdy procedura skończy robić swoje - wtedy wszystko wraca do normy.

3

Wywołujesz w pętli dość czasochłonną operację stąd efekt zamrożenia spróbuj w niej wstawić Application.ProcessMessages;.

0

@kAzek - No teraz znacznie lepiej :)
Umieściłem to wewnątrz pętli i okno zaczęło się normalnie zachowywać.
Nie wiem tylko jak tego użyć w przypadku pierwszej części procedury gdzie nie ma pętli a apka czeka na odpowiedź serwera.

1

Tu nie można nic zrobić poza zastosowaniem osobnego wątku w którym będą pobierane dane z bazy ale trzeba pamiętać o synchronizacji przy aktualizowaniu komponentów VCL.

2

Nie przeglądałem internalsów tego komponentu, jednak jego renderowanie odbywa się w ramach głównego wątku (pewnie zwykły timer). Tak więc jeśli wykonasz długotrwałą operację to komponent zostanie odmalowany dopiero po jej zakończeniu, po odblokowaniu kolejki komunikatów. Ten kod musisz wstawić do osobnego wątku.

Używałem tego stylu paska w prostym instalatorze, który wątku pobocznego nie wykorzystywał. Kod wypakowujący pliki z zasobów i zapisujący je na dysku działał w ramach głównego wątku, ale aby kontrolka była odmalowywana, wołałem ProcessMessages po każdorazowym zapisie pliku na dysku. Pasek animował się płynnie, ale tylko dlatego, że zapisywane pliki były relatywnie małe.

0

Wątki ? Ja prosty człowiek jestem, amator :D. Poradziłem sobie inaczej. Nie udało mi się wprawdzie dowiedzieć jak działa .Caption (bo nic nie widać mimo postawienia tekstu), a .BarShowText ma tylko formatowany tekst (a raczej cyferki) więc stwierdziłem iż łatwiej na ten moment zmienić treść przycisku wyzwalającego procedure :)

0

Jak jeszcze kiedyś zajmowałem się VCL, to zawsze "prrogramiści" (Delphi, C++ Builder) ratowali się tym process messages przed wątkami, bo wątki były przeciez trudne. Jak widzę, niewiele sie zmieniło tu do dziś.

Dobrze, że nowsze technologie zwykle już tego nie mają i wymuszają prawidłowe podejście, np programując na Androida próba wywołania jakiejkolwiek operacji sieciowej w głównym wątku od razu spowoduje wyjątek i wywali aplikację.

0
titako napisał(a):

Wątki ? Ja prosty człowiek jestem, amator :D. Poradziłem sobie inaczej.

W tym przypadku użycie wątku pobocznego nie powinno być jakoś szczególnie trudne. Ale skoro sobie poradziłeś inaczej, to nie ma sprawy.

Nie udało mi się wprawdzie dowiedzieć jak działa .Caption (bo nic nie widać mimo postawienia tekstu), a .BarShowText ma tylko formatowany tekst (a raczej cyferki) […]

Może być tak, że właściwość Caption wcale nie jest wykorzystywana, a jest dostępna dzięki jej dziedziczeniu z klasy bazowej (tu: TControl). Może być również tak, że te właściwości wykorzystywane są przez bieżący widgetset i faktycznie używane tylko w obrębie danego systemu operacyjnego i/lub schematu.

Pod WinXP ze schematem Luna, zmodyfikowanie tych właściwości niczego wizualnie nie zmienia. Nie wiem na jakim systemie testujesz ten komponent, ale fajnie by było, gdybyś pokazał jakieś zrzuty.

0
kulson napisał(a):

Jak jeszcze kiedyś zajmowałem się VCL, to zawsze "prrogramiści" (Delphi, C++ Builder) […]

Dlaczego ”programiści” w ząbkach? Masz jakiś problem do programistów używających tych narzędzi?

[…] ratowali się tym process messages przed wątkami, bo wątki były przeciez trudne.

Wątki były zbyt trudne? Dobry żart. Klasa TThread istnieje od dobrych 20 lat i jest banalna w obsłudze. Widać słabo „zajmowałeś się VCL”, skoro takich rzeczy nie potrafiłeś okiełznać. A no tak, „koledzy się ratowali”, racja.

Jak widzę, niewiele sie zmieniło tu do dziś.

Nom, nadal klasa TThread jest obecna i łatwo się jej używa. Co nie zmienia faktu, że wątki poboczne nie wszędzie są potrzebne i absolutnie nie należy ich używać wszędzie gdzie się da. W tym przypadku jest to potrzebne, więc takie rozwiązanie zostało zasugerowane.

Natomiast miałem do czynienia z różnymi kodami, w których autor używał wątków pobocznych, czym jedynie komplikował logikę. Widziałem też kody komponentów (komponentów!), które używały wątków pobocznych do określania stylu własnego wyglądu, co normalnie implementuje się za pomocą timerów. Przesadzić czy skomplikować kod bardzo łatwo.

Dobrze, że nowsze technologie zwykle już tego nie mają i wymuszają prawidłowe podejście, np programując na Androida próba wywołania jakiejkolwiek operacji sieciowej w głównym wątku od razu spowoduje wyjątek i wywali aplikację.

Delphi jest „nowszą” technologią – cały czas jest rozwijane, wychodzą nowe wersje.

Wracając do meritum – czy ten wątek dotyczy Delphi? Nie, dotyczy Lazarusa. Czy ten wątek dotyczy porównania technologii? Nie. Czy wątek dotyczy zagadnień sieciowych na Androidzie? Nie, więc jeśli nie masz nic sensownego do dodania w temacie to się nie wypowiadaj. Nie masz w sumie bladego pojęcia o Delphi, ale do ciągnięcia off-topu i krytyki jesteś pierwszy.

Jak nie chcesz pomóc to przynajmniej nie przeszkadzaj – nie będę więcej upominać.

0

Panowie - spokojnie :)
Na życzenie - komponent TProgressBar pod Win10 64bit
progbarr.png
Niestety nie udało mi sie zmienić koloru :/ - chyba że **.color ** jest od czegoś innego. I tego po prostu nie widać.
Może to jakieś ustawienia projektu, które blokują takie zmiany. Pasek wygląda jak większość w tym systemie.

1
titako napisał(a):

Na życzenie - komponent TProgressBar pod Win10 64bit

Pod Windows ta właściwość najwyraźniej nie jest wykorzystywana, przez żaden schemat. W innych systemach pasek może dodatkowo wyświetlać jakiś tekst (np. procenty na pasku), stąd jej istnienie w tej klasie.

Niestety nie udało mi sie zmienić koloru :/ - chyba że **.color ** jest od czegoś innego. I tego po prostu nie widać.

Zmiana wartości tej właściwości niczego nie zmieni, bo wygląd standardowych komponentów determinowany jest przez system. Tak więc kontrolki zawsze wyglądają tak, jak w pozostałej części systemu.

Może to jakieś ustawienia projektu, które blokują takie zmiany. Pasek wygląda jak większość w tym systemie.

W oknie ustawień możesz odznaczyć opcję Use manifest resource (and enable themes), dzięki czemu kontrolki będą posiadały wygląd domyślny (à la Win98). Wtedy też możliwa jest zmiana koloru paska – właściwość Color akurat dotyczy jego tła.

Tyle że wtedy wszystkie kontrolki będą nieoskinowane, we wszystkich oknach programu. Poza tym, wyłączenie tej opcji automatycznie uniemożliwi określenie poziomu uprawnień i innych informacji, które w takim manifeście się znajdują.


Tak więc jeśli chcesz customizować wygląd okien, to skorzystaj z niestandardowych kontrolek, które do renderowania nie używają widgetsetu. Jest ich masa w sieci, więc jest w czym wybierać. Ewentualnie możesz napisać swoje.

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