3 votes

FMX Delphi 10.2 Afficher un formulaire ou un panneau d'attente pendant l'exécution d'une tâche

J'ai plusieurs tâches sur le clic du bouton.

eg.

  1. Formulaire de présentation ou panneau d'attente ....
  2. Charger les données de la base de données (durée 5-10 secondes)
  3. Effacer tous les champs TEdit
  4. Masquer le formulaire ou le panneau d'attente ....
  5. ShowMessage('completed')

Est-il possible, après avoir cliqué sur le bouton, d'afficher le panneau ou le formulaire "Veuillez patienter" et, une fois le formulaire rempli, de masquer ce panneau ?

Comment synchroniser les tâches d'exécution une par une.

Ou toute autre solution simple.

5voto

Alberto Miola Points 2331

Il s'agit d'un exemple simple qui crée un "placeholder" qui ressemble à ceci :

enter image description here

Le rectangle a un arrière-plan noir et contient une mise en page qui est alignée à Center ; à l'intérieur, vous pouvez trouver une étiquette (alignée à Top ) et un arc (aligné sur Client ). Le code est ici :

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 418
  ClientWidth = 490
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [Desktop]
  OnCreate = FormCreate
  DesignerMasterStyle = 0
  object Rectangle1: TRectangle
    Align = Client
    Fill.Color = xFF222222
    Size.Width = 490.000000000000000000
    Size.Height = 418.000000000000000000
    Size.PlatformDefault = False
    Visible = False
    object Layout1: TLayout
      Align = Center
      Size.Width = 170.000000000000000000
      Size.Height = 102.000000000000000000
      Size.PlatformDefault = False
      TabOrder = 0
      object Label1: TLabel
        Align = Top
        StyledSettings = [Family, Size, Style]
        Size.Width = 170.000000000000000000
        Size.Height = 41.000000000000000000
        Size.PlatformDefault = False
        TextSettings.FontColor = claWhite
        TextSettings.HorzAlign = Center
        Text = 'Please wait'
        TabOrder = 0
      end
      object Arc1: TArc
        Align = Center
        Size.Width = 50.000000000000000000
        Size.Height = 50.000000000000000000
        Size.PlatformDefault = False
        Stroke.Color = claCoral
        EndAngle = -90.000000000000000000
        object FloatAnimation1: TFloatAnimation
          Enabled = True
          Duration = 1.000000000000000000
          Loop = True
          PropertyName = 'RotationAngle'
          StartValue = 0.000000000000000000
          StopValue = 360.000000000000000000
        end
      end
    end
  end
end

En Visible du rectangle est mise à False afin que vous ne voyiez pas immédiatement le rectangle. Notez que j'ai créé une animation dans le composant arc pour que vous puissiez le voir tourner sur lui-même :

enter image description here

De cette façon, vous pouvez imiter un spinner de chargement. Ensuite, j'ai ajouté ce code dans la section OnCreate du formulaire, à titre d'exemple de ce que vous pouvez faire.

procedure TForm1.FormCreate(Sender: TObject);
begin
  TTask.Run(procedure
            begin
              TThread.Synchronize(nil, procedure
                                 begin
                                   Rectangle1.Visible := true;
                                   //Rectangle1.BringToFront;
                                   // ^ call the above if needed, just to be sure
                                   // that you'll always see the rectangle on screen 
                                 end);

              Sleep(4000);

              TThread.Synchronize(nil, procedure
                                 begin
                                   Rectangle1.Visible := false;
                                   ShowMessage('Finish!');
                                 end);
            end);
end;

En Sleep(4000) simule une longue tâche et ce morceau de code devrait être remplacé par vos tâches. En fait, je ferais quelque chose comme ça :

procedure TForm1.FormCreate(Sender: TObject);
begin
  TTask.Run(procedure
            var
              arr: array [0..1] of ITask;
            begin
              TThread.Synchronize(nil, procedure
                                 begin
                                   Rectangle1.Visible := true;
                                   Rectangle1.BringToFront;
                                 end);

              arr[0] := TTask.Run(procedure
                                  begin
                                    //load data from the database
                                  end);

              arr[1] := TTask.Run(procedure
                                  begin
                                    //something else
                                  end);

              //this call is blocking but you are calling this in a worker thread!
              //your UI won't freeze and at the end you'll see the message appearing
              TTask.WaitForAll(arr);
              TThread.Synchronize(nil, procedure
                                 begin
                                   Rectangle1.Visible := false;
                                   ShowMessage('Finish!');
                                 end);
            end);
end;

Bien sûr, vous devez placer ce code dans un ButtonClick et non dans un gestionnaire d'événement FormCreate !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X