Formular mit Bild kurz aufblenden, Windows gut, Linux nicht

Formular mit Bild kurz aufblenden, Windows gut, Linux nicht

Beitragvon Der Proband » 24. Mai 2016, 18:24 Formular mit Bild kurz aufblenden, Windows gut, Linux nicht

Hallo,
ich programmiere schon länger mit Pascal, aber noch nicht lange mit Lazarus. Jetzt hänge ich an einem Problem, bei dem ich nicht mehr weiter komme. Auch Google hat mir bisher noch nicht geholfen.
Die Aufgabe ist, auf das eigentlich Problem heruntergebrochen, einfach zu beschreiben: Bei Drücken eines Buttons im Hauptformular soll sich ein zweites Formular öffnen und ein Bild anzeigen. Nach einer gewissen Zeit soll sich das Formular wieder schließen. Umgestzt habe ich das wie folgt:

Code: Alles auswählen
procedure TForm1.Button1Click(Sender: TObject);
begin
   form2.show;
   form2.Image1.Picture.LoadFromFile('Test.jpg');
   form2.refresh;
   sleep(3000);
   form2.hide;
end;


Das Ganze funktioniert unter Windows wie es soll. Auf dem raspberry PI mit raspbian Jessie geht das Fenster auf, enthält aber kein Bild. Lasse ich sleep und hide weg, wird das Bild dargestellt, aber natürlich bleibt das Fenster offen. Die Darstellung des Bildes ist also nicht das Problem, wohl eher der sleep Befehl. Wie kann man das Problem umgehen und was ist die Ursache für das Unterschiedliche Verhalten unter Windows und Linux?
Zuletzt geändert von Lori am 24. Mai 2016, 18:25, insgesamt 1-mal geändert.
Grund: Highlighter
Der Proband
 
Beiträge: 7
Registriert: 24. Mai 2016, 08:47

Beitragvon theo » 24. Mai 2016, 18:35 Re: Formular mit Bild kurz aufblenden, Windows gut, Linux ni

Sleep ist nicht so das Wahre in der GUI Programmierung. Nimm lieber einen TTimer.
theo
 
Beiträge: 8058
Registriert: 11. Sep 2006, 18:01

Beitragvon FXMaveric » 24. Mai 2016, 20:54 Re: Formular mit Bild kurz aufblenden, Windows gut, Linux ni

theo hat recht.

Kurz: sleep hält den GUI-Threadoder MainThread an, in dem auch die grafische Anzeige abläuft.
Das Show und Refresh löst ein Invalidate aus, welches asynchron abgearbeitet wird. Es kommt also gar nicht zu Anzeige bevor du das Fenster schließt, da der Anzeigethread ja Pause macht.
Mit einem Timer sollte es keine Probleme geben.

Gruß
FX
FXMaveric
 
Beiträge: 19
Registriert: 7. Jan 2009, 08:59

Beitragvon Komoluna » 25. Mai 2016, 01:22 Re: Formular mit Bild kurz aufblenden, Windows gut, Linux ni

Mich wunderts eher, dass es unter Windows trotzdem klappt.

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.
Komoluna
 
Beiträge: 565
Registriert: 26. Aug 2012, 08:03
OS, Lazarus, FPC: Windows(7, 10), Linux(Ubuntu, Kali) | 
CPU-Target: 64Bit
Nach oben

Beitragvon SoE » 25. Mai 2016, 03:04 Re: Formular mit Bild kurz aufblenden, Windows gut, Linux ni

Versuch mal
Code: Alles auswählen
Form2.Update;
vor dem Sleep.

Ich benutze bei einem selbstgebauten Button oft "Sleep" um das zweite PNG beim "MouseDown" anzuzeigen und ohne
Code: Alles auswählen
FormXYZ.Update
funzt das nicht.
Code: Alles auswählen
 
 form2.Image1.Picture.LoadFromFile('Test.jpg');
 form2.show;
 form2.Update;
 sleep(3000);
 form2.hide;
 


Willst du nicht lieber erst beim Klick auf den Button das Fenster erstellen lassen?
Oder dauert das zu lange? Das Bild könnte man auch in "FormCreate" laden lassen... (FormCreate des Hauptfensters)
Code: Alles auswählen
 
Procedure TForm1.Button1Click(Sender: TObject);
  Var
   Info: TForm;
   Pic : TImage;
 Begin
  Try
   Info         := TForm.Create(Nil);
   Info.Position:= poScreenCenter;
   Info.Height  := 300;
   Info.Width   := 300;
 
   Pic       := TImage.Create(Nil);
   Pic.Align := alClient;
   Pic.Parent:= Info;
   Pic.Picture.LoadFromFile('I:\(DOWNLOADS)\Logo.png');
 
   Info.Show;
   Info.Update;
   Sleep(3000);
  Finally
   FreeAndNil(Pic);
   Info.Release;
   Info:= Nil;
  End;
 End;     
 


Wenn man in den 3 Sekunden mit dem Hauptfenster etwas machen soll, dann wäre natürlich wie schon von den anderen erwähnt ein Timer 'ne gute Idee...
SoE
 
Beiträge: 84
Registriert: 31. Aug 2015, 00:51
OS, Lazarus, FPC: Windows 7 (x64 Sp1), Lazarus 1.6.0 x64 FPC 3.0.0 | 
CPU-Target: x64
Nach oben

Beitragvon SoE » 25. Mai 2016, 03:36 Re: Formular mit Bild kurz aufblenden, Windows gut, Linux ni

Mit Timer könnte man es so machen...
Vielleicht gibt es auch noch 'ne bessere Lösung...

Code: Alles auswählen
 
Unit uForm2;
 {$mode objfpc}{$H+}
Interface
 Uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, StdCtrls, ExtCtrls;
 
 Type
  TForm1 = Class(TForm)
   Button1: TButton;
 
    Procedure Button1Click(Sender: TObject);
    Procedure SleepTimer  (Sender: TObject);
  End;
 
 VAR
  Form1: TForm1;
 
Implementation
 {$R *.lfm}
 
 
Procedure TForm1.Button1Click(Sender: TObject);
  Var
   Info: TForm;
   Pic : TImage;
   Ti  : TTimer;
 Begin
  Info         := TForm.Create(Nil);
  Info.Position:= poScreenCenter;
  Info.Height  := 300;
  Info.Width   := 300;
 
  Pic       := TImage.Create(Info);
  Pic.Align := alClient;
  Pic.Parent:= Info;
  Pic.Picture.LoadFromFile('I:\(DOWNLOADS)\Logo.png');
 
  Ti         := TTimer.Create(Info);
  Ti.Interval:= 3000;
  Ti.Enabled := False;
  Ti.OnTimer := @SleepTimer;
 
  Info.Show;
  //ohne Update;
  Ti.Enabled:=True;
 End;
 
 
Procedure TForm1.SleepTimer(Sender: TObject);
 Begin
  TTimer(Sender).Enabled:= False;
  TTimer(Sender).Owner.Free;
 End;
 
End.                       
 
SoE
 
Beiträge: 84
Registriert: 31. Aug 2015, 00:51
OS, Lazarus, FPC: Windows 7 (x64 Sp1), Lazarus 1.6.0 x64 FPC 3.0.0 | 
CPU-Target: x64
Nach oben

Beitragvon FXMaveric » 25. Mai 2016, 06:26 Re: Formular mit Bild kurz aufblenden, Windows gut, Linux ni

Das es unter Windows klappt (klappen kann), hängt mit der anderen Nachrichtenkettenimplementation und dem Timing zusammen.
Linux hat von Haus aus keine Nachrichtenkette/Messsages wie Windows und wird quasi von FPC emuliert.
FXMaveric
 
Beiträge: 19
Registriert: 7. Jan 2009, 08:59

Beitragvon mschnell » 25. Mai 2016, 08:14 Re: Formular mit Bild kurz aufblenden, Windows gut, Linux ni

theo hat geschrieben:Sleep ist nicht so das Wahre in der GUI Programmierung.


+1

Ich würde es allerdings härter ausdrücken: Sleep ist im Main-Thread verboten, egal welches Betriebssystem.

-Michael
mschnell
 
Beiträge: 3226
Registriert: 11. Sep 2006, 09:24
Wohnort: Krefeld
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ) | 
CPU-Target: X32 / X64 / ARMv5
Nach oben

Beitragvon Requion » 25. Mai 2016, 08:55 Re: Formular mit Bild kurz aufblenden, Windows gut, Linux ni

mschnell hat geschrieben:
theo hat geschrieben:Sleep ist nicht so das Wahre in der GUI Programmierung.


+1

Ich würde es allerdings härter ausdrücken: Sleep ist im Main-Thread verboten, egal welches Betriebssystem.

-Michael

Ach warum denn so hart? Ist doch toll wenn der Nutzer immer mal Pause machen kann weil das Programm hängt :D *Ironie aus*.
Mfg Requion

Das beste an Standards ist, dass es so viele davon gibt.
Requion
 
Beiträge: 106
Registriert: 3. Feb 2016, 09:39
Wohnort: nahe Grimma
OS, Lazarus, FPC: Linux(Arch Linux(+ARM)/Minibian) (L 1.6.0 FPC 3.0.0) | 
CPU-Target: 32/64Bit,ARM(RPi)
Nach oben

Beitragvon SoE » 25. Mai 2016, 14:58 Re: Formular mit Bild kurz aufblenden, Windows gut, Linux ni

Vielleicht sollte man das Laden besser so machen:
Oder du lädst das Bild aus einer Ressource...
Code: Alles auswählen
 
  Pic       := TImage.Create(Info);
  Pic.Align := alClient;
  Pic.Parent:= Info;
 
   If FileExists('I:\(DOWNLOADS)\Logo.png')
   Then
    Begin
     Try
      Pic.Picture.LoadFromFile('I:\(DOWNLOADS)\Logo.png');
     Except
      On E: Exception
      Do
       Begin
        // Fenster anzeigen oder nur ein ErrorLog, sollte zu deinem restlichen
        // Exception-Handling passen...
        // nach deinem Text vielleicht noch: E.ClassName+#13#10+E.Message
       End;
     End;
    End;     
 


by the way:

Vielleicht kennst du das ja schon, ist sehr praktisch:
Wenn du im Menü auf "Projekt", "Projekteinstellungen" gehst und dann auf "Pfade" klickst (unter Compilereinstellungen), dann kannst du in der ersten Zeile (Erstellmodi) auf den Button mit den drei Punkten klicken und in dem sich öffnenden Fenster den Button "Debug- und Release-Modi erstellen" klicken. Danach wird automatisch der Debug-Modus ausgewählt und es erscheint ein neuer kleiner Button links neben dem Compilieren(Start)-Button in der Schnellstartleiste.

Wenn du jetzt auf Start(Compilieren) drückst wird nach der Programmausführung ein Error-Dialog angezeigt, der dir in der vierten Zeile "unfreed memory blocks: .." anzeigt. Damit kann man schön sehen ob auch alles wieder freigegeben wurde. Ob das auch funktioniert wenn man direkt über die API Speicher reserviert hab' ich noch nicht ausprobiert...

Und wenn du den Modus auf "Release" stellst, hast du eine viel kleinere Echse ohne die DebugInformationen.
SoE
 
Beiträge: 84
Registriert: 31. Aug 2015, 00:51
OS, Lazarus, FPC: Windows 7 (x64 Sp1), Lazarus 1.6.0 x64 FPC 3.0.0 | 
CPU-Target: x64
Nach oben

Beitragvon Der Proband » 25. Mai 2016, 19:44 Re: Formular mit Bild kurz aufblenden, Windows gut, Linux ni

Hallo,
ich bedanke mich schonmal für das schnelle und umfangreiche feedback. In den nächsten Tagen werde ich das ausprobieren und mich wieder, vielleicht auch mit Fragen, melden. Die eigentliche Aufgabe war ein Webcambild mittels Synapse zu laden und anschließend kurzzeitig anzuzeigen und kein Bild aus einer lokal gespeicherten Datei. Das Problem mit dem Sleep war jedoch bei beiden Aufgaben das gleiche und ich denke, die Lösung wird auch bei dem anderen Anwedungsfall, der vielleicht etwas komplexer ist, funtionieren.
Nochmals vielen Dank.
Der Proband
 
Beiträge: 7
Registriert: 24. Mai 2016, 08:47

Beitragvon SoE » 26. Mai 2016, 16:34 Re: Formular mit Bild kurz aufblenden, Windows gut, Linux ni

Das Einfachste und Beste wäre wahrscheinlich das hier:

Code: Alles auswählen
 
Unit uForm2;
 {$mode objfpc}{$H+}
Interface
 Uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, StdCtrls, ExtCtrls;
 
 Type
  TForm1 = Class(TForm)
 
   Button1: TButton;
 
    Procedure Button1Click (Sender: TObject);
    Procedure CloseClick   (Sender: TObject;  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  End;
 
 VAR
  Form1: TForm1;
 
Implementation
 {$R *.lfm}
 
 
Procedure TForm1.Button1Click(Sender: TObject);
  Var
   Info: TForm;
   Pic : TImage;
 Begin
  Info         := TForm.Create(Nil);
  Info.Position:= poScreenCenter;
  Info.Height  := 300;
  Info.Width   := 300;
 
  Pic          := TImage.Create(Info);
  Pic.Align    := alClient;
  Pic.Parent   := Info;
  Pic.OnMouseUp:= @CloseClick;
  Pic.Picture.LoadFromFile('I:\(DOWNLOADS)\Logo.png');
 
  Info.Show;
 End;
 
 
Procedure TForm1.CloseClick(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
 Begin
  If Button = mbRight
  Then TImage(Sender).Owner.Free;
 End;
 
 
End.           
 


Wenn etwas angezeigt werden soll, dann kann man davon ausgehen, dass jemand das Angezeigte sehen soll und dann hat dieser Jemand vielleicht ja sogar eine Möglichkeit an dieser Stelle mit dem Programm zu interagieren. Daraus ergibt sich dann, dass es möglicherweise besser ist auf das ZeitIntervall zu verzichten, da dann jeder Nutzer selber festlegen kann wann er das Fenster schließen möchte.
Das Intervall würde bei Nutzerinteraktion nur dazu führen, dass ein Nutzer sagt "...zu kurz..." und ein anderer sagt "...zu lang..." und das könnte man einfach von vornherein umgehen...

Ist nur so ein Gedanke... :-)
SoE
 
Beiträge: 84
Registriert: 31. Aug 2015, 00:51
OS, Lazarus, FPC: Windows 7 (x64 Sp1), Lazarus 1.6.0 x64 FPC 3.0.0 | 
CPU-Target: x64
Nach oben

• Themenende •

Zurück zu Linux



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste

porpoises-institution
accuracy-worried