Programm ohne GUI

Für Fragen von Einsteigern und Programmieranfängern...

Programm ohne GUI

Beitragvon DL3AD » 29. Okt 2017, 11:36 Programm ohne GUI

Hallo,

ich programmiere nun schon eine ganze weile mit Lazarus GUI Anwendungen - habe aber noch nie eine Anwendung ohne GUI gemacht.
Nun möchte ich mal ein einfaches Programm erstellen das im Hintergrund läuft bis ich es beende (mit exit).
Wenn ich ein neues Projekt erstelle dann wähle ich Programm und bekomme dann folgende Struktur vorgegeben
Code: Alles auswählen
 
program project1;
 
{$mode objfpc}{$H+}
 
uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads;
  {$ENDIF}{$ENDIF}
  Classes
  { you can add units after this };
 
begin
  writeln('TEST');//eingefügt zum Testen der Ausgabe auf Konsole
  readln;
end.         
 


Nun habe ich das Probelm dass ich nicht weiter komme aus Unwissenheit
Ich habe mit einer GUI Anwendung folgende Testfunktionalität erstellt und möchte diese nun in das Programm ohne GUI überführen.
Die Memoausgabe kann man ja testweise mit writeln erschlagen.
Code: Alles auswählen
 
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, blcksock, uplaysound;
type
  { TForm1 }
  TForm1 = class(TForm)
    Memo1: TMemo;
    playsound1: Tplaysound;
    Timer1: TTimer;
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormShow(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { private declarations }
    procedure InitSocket;
    procedure DeInitSocket;
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
  UDPResiveSocket: TUDPBlockSocket;
 
implementation
{$R *.lfm}
{ TForm1 }
//Initialisierungen
procedure TForm1.FormShow(Sender: TObject);
begin
  InitSocket;
end;
 
//Aktionen zum Form schließen
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  DeInitSocket;
end;
 
//Timer zum Daten abrufen
procedure TForm1.Timer1Timer(Sender: TObject);
var
  UDPRx: string;
begin
  Timer1.Enabled:= false;
  UDPRx:= UDPResiveSocket.RecvPacket(50);
  if UDPRx <> '' then
  begin
    Memo1.Lines.Add('>' + UDPRx);
    playsound1.SoundFile:='post.wav';
    playsound1.Execute;
  end;
  Timer1.Enabled:= true;
end;
 
//UDP Socket erzeugen
procedure TForm1.InitSocket;
begin
  if UDPResiveSocket <> nil then DeInitSocket;
 
  UDPResiveSocket:= TUDPBlockSocket.Create;
  UDPResiveSocket.CreateSocket;
  UDPResiveSocket.Bind('192.168.2.116','10001');
end;
 
//UDP Socket freigeben
procedure TForm1.DeInitSocket;
begin
  UDPResiveSocket.CloseSocket;
  UDPResiveSocket.Free;
  UDPResiveSocket:= nil;
end;
end.
 


Wie muss der Code aus der GUI Anwendung in das Programm eingefügt werden ?
Muss man hier dann eine "main loop"(mit Abbruchbedingung) erstellen ?

Gruß Frank
DL3AD
 
Beiträge: 300
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.6.4 FPC 3.0.2) und Debian 8 (L 1.6.4 FPC 3.0.2) | 
CPU-Target: 32Bit
Nach oben

Beitragvon Soner » 29. Okt 2017, 11:48 Re: Programm ohne GUI

Code: Alles auswählen
program Project1;
uses crt;
var c: char;
begin
   repeat
 
     //hier ist "mainloop"
     Writeln('Läuft so lange bis du [ESC]-Taste drückst');
 
     delay(10); //warten, sonst wird die Cpu-Auslastung hoch, (lüfter bei laptops!)
 
     if KeyPressed then c:=ReadKey;
   until c=#27;
end.


Edit:
delay hinzugefügt.
Soner
 
Beiträge: 364
Registriert: 26. Sep 2012, 23:07
Wohnort: Hamburg
OS, Lazarus, FPC: Win7Pro-32Bit, Immer letzte Lazarus Release mit SVN-Fixes | 
CPU-Target: 32Bit
Nach oben

Beitragvon DL3AD » 29. Okt 2017, 12:11 Re: Programm ohne GUI

... Dass mit der Mainloop habe ich mir ja schon gedacht - aber wie und wo binde ich den Rest ein wie z.B. TTimer, Tplaysound u.s.w. ?
DL3AD
 
Beiträge: 300
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.6.4 FPC 3.0.2) und Debian 8 (L 1.6.4 FPC 3.0.2) | 
CPU-Target: 32Bit
Nach oben

Beitragvon Soner » 29. Okt 2017, 13:08 Re: Programm ohne GUI

In dem du entweder die Klasse TForm1 einfügst und anpasst oder alles als Prozeuduren neu einfügst.
Ich verstehe nicht wiese du :
UDPResiveSocket: TUDPBlockSocket;
global definiert hast. Das wird doch nur in dein Formular verwendet.

Ich habe für dein TForm1 eingefügt und angepasst, lies mein Kommentare, besonders für uplaysound.
Du mußt natürlich für das Projekt benötigte Packages einfügen.


Code: Alles auswählen
 
program project1;
 
{$mode objfpc}{$H+}
 
uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads;
  {$ENDIF}{$ENDIF}
  Classes
  { you can add units after this }
  ,crt,
 
  interfaces, // wegen uplaysound, z.B. mit uplaysound entfernen!
  uplaysound, // uplaysoundist problematisch das braucht lcl
              // du muß andere sound bibliothek nehmen, z.b. uos von fredvs
 
 
  blcksock,   // Abhängigkeit laz_synapse, OK
  fptimer     //NEU für timer
  ;
 
 
 
type
  { TForm1 }
  TForm1 = class(TComponent)//weg damit: (TForm)
    //weg damit: Memo1: TMemo;
    playsound1: Tplaysound;
    Timer1: TfpTimer; //<--- ändern TTImer
    procedure FormClose;//weg damit: (Sender: TObject; var CloseAction: TCloseAction);
    procedure FormShow(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { private declarations }
    procedure InitSocket;
    procedure DeInitSocket;
  public
    { public declarations }
    constructor Create(AOwner: TComponent); override;           //neu
  end;
 
var
  Form1: TForm1;
  UDPResiveSocket: TUDPBlockSocket;
 
//weg damit: implementation
//weg damit: {$R *.lfm}
 
{ TForm1 }
//NEU
constructor TForm1.Create(AOwner: TComponent);           //neu
begin
  inherited Create(AOwner);
  //die genauen parameter kannst du aus *.lfm Datei aus GUI Programm entnehmen
  playsound1:= Tplaysound.Create(self);
 
  Timer1:= TfpTimer.Create(self);
  Timer1.OnTimer:=@Timer1Timer;
  Timer1.Enabled:=true;//eigentlich sollte das starten in procedure TForm1.InitSocket; s
                       //weil UDPResiveSocket dort erstellt wird, wenn timer früher startet dann,
                       //hast du Problem
 
end;
 
//Initialisierungen
procedure TForm1.FormShow(Sender: TObject);
begin
  InitSocket;
end;
 
//Aktionen zum Form schließen
procedure TForm1.FormClose;//weg damit: (Sender: TObject; var CloseAction: TCloseAction);
begin
  Timer1.Enabled:=false; //NEU !
  DeInitSocket;
end;
 
//Timer zum Daten abrufen
procedure TForm1.Timer1Timer(Sender: TObject);
var
  UDPRx: string;
begin
  Timer1.Enabled:= false;
  UDPRx:= UDPResiveSocket.RecvPacket(50);
  if UDPRx <> '' then
  begin
    Writeln('>' + UDPRx);//weg damit: Memo1.Lines.Add('>' + UDPRx);
    playsound1.SoundFile:='post.wav';
    playsound1.Execute;
  end;
  Timer1.Enabled:= true;
end;
 
//UDP Socket erzeugen
procedure TForm1.InitSocket;
begin
  if UDPResiveSocket <> nil then DeInitSocket;
 
  UDPResiveSocket:= TUDPBlockSocket.Create;
  UDPResiveSocket.CreateSocket;
  UDPResiveSocket.Bind('192.168.2.116','10001');
end;
 
//UDP Socket freigeben
procedure TForm1.DeInitSocket;
begin
  UDPResiveSocket.CloseSocket;
  UDPResiveSocket.Free;
  UDPResiveSocket:= nil;
end;
 
var c: char;
begin
  Form1:= TForm1.Create(nil);
  try
 
   Form1.FormShow(Form1);
 
   repeat
 
     //hier ist "mainloop"
     Writeln('Läuft so lange bis du [ESC]-Taste drückst');
 
     delay(10); //warten, sonst wird die Cpu-Auslastung hoch, (lüfter bei laptops!)
 
     if KeyPressed then c:=ReadKey;
   until c=#27;
 
   Form1.FormClose;
 
 finally
   Form1.Free;
 end;
end.
 
Soner
 
Beiträge: 364
Registriert: 26. Sep 2012, 23:07
Wohnort: Hamburg
OS, Lazarus, FPC: Win7Pro-32Bit, Immer letzte Lazarus Release mit SVN-Fixes | 
CPU-Target: 32Bit
Nach oben

Beitragvon DL3AD » 29. Okt 2017, 13:35 Re: Programm ohne GUI

... kann der ganze Form1 Kram nicht raus ?
Letztendlich möchte ich das GUI Beispiel als nicht GUI also auf Konsole haben.
DL3AD
 
Beiträge: 300
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.6.4 FPC 3.0.2) und Debian 8 (L 1.6.4 FPC 3.0.2) | 
CPU-Target: 32Bit
Nach oben

Beitragvon Mathias » 29. Okt 2017, 13:50 Re: Programm ohne GUI

Natürlich kann man das Form Zeugs entfernen.
Dein Programm, muss aussehen wie zu TP-Zeiten.

Was soll dein Programm schlussendlich können ?
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3201
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Soner » 29. Okt 2017, 13:59 Re: Programm ohne GUI

Da ist doch kein GUI mehr. Wenn dich der Name TForm1 stört, dann benenne das um.
Du kannst es auch zu Prozeduren umwandeln, aber für den Timer.OnTimer brauchst du eine Klasse.
Das einzige was hier stört is uplaysound-Unit. Das habe ich ja als Kommentar geschrieben.
Soner
 
Beiträge: 364
Registriert: 26. Sep 2012, 23:07
Wohnort: Hamburg
OS, Lazarus, FPC: Win7Pro-32Bit, Immer letzte Lazarus Release mit SVN-Fixes | 
CPU-Target: 32Bit
Nach oben

Beitragvon DL3AD » 29. Okt 2017, 14:10 Re: Programm ohne GUI

Hallo Mathias,

1. es soll im Hintergrund laufen
2. es soll in Abhängigkeit von einem eintreffendem UDP String eine zugehörige Sounddatei abspielen (muss dann noch implementiert werden)

Die simpelste Lösung währe Form1.Hide - aber ich möchte lernen wie man es ohne GUI macht, ohne schnikschnack und ganz simpel. :mrgreen:
DL3AD
 
Beiträge: 300
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.6.4 FPC 3.0.2) und Debian 8 (L 1.6.4 FPC 3.0.2) | 
CPU-Target: 32Bit
Nach oben

Beitragvon Mathias » 29. Okt 2017, 14:40 Re: Programm ohne GUI

Mit folgender Grundstruktur müsste es gehen.

Code: Alles auswählen
udp Create
Repeat
  If udp then Sound
  Delay
Until esc
Udp Free


Somit braucht es auch keinen Timer.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3201
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon DL3AD » 29. Okt 2017, 14:49 Re: Programm ohne GUI

... ja, hmm mir fehlt die Kenntniss wie ich es in diese Struktur packe ich brauche immer ein konkretes Beispiel.
Hilfreich währe wenn jemand es mal anhand meines vorgegebenen GUI Beispieles macht.
Das was Soner gemacht hat ist irgendwie gefrickel - sorry ist nicht bös gemeint.
DL3AD
 
Beiträge: 300
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.6.4 FPC 3.0.2) und Debian 8 (L 1.6.4 FPC 3.0.2) | 
CPU-Target: 32Bit
Nach oben

Beitragvon mse » 29. Okt 2017, 15:56 Re: Programm ohne GUI

TTimer und allgemein Ereignis-gesteuerte Anwendungen brauchen eine "main event queue". AFAIK stellt Lazarus dies nur mittels zugrunde liegendem Widgetset zur Verfügung. In MSEgui würde man statt "uses msegui" "uses msenogui" schreiben, TApplication wird dann unabhängig von einem Graphik- und Fenstersystem. Beispiele sind hier:
https://gitlab.com/mseide-msegui/mseuni ... ials/nogui
Fred's "consoleplay" Beispiel zeigt eine andere Art von Programmen ohne GUI.
DL3AD hat geschrieben:aber ich möchte lernen wie man es ohne GUI macht, ohne schnikschnack und ganz simpel.

Konsolenprogramme werden leider sehr rasch nicht mehr simpel sobald asynchrone Ereignisse dazukommen. Die Entwicklung von ereignisgesteuerten Frameworks kommt ja nicht von Ungefähr...
mse
 
Beiträge: 1679
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.4.2,git master FPC 3.0,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon DL3AD » 29. Okt 2017, 16:21 Re: Programm ohne GUI

Hallo mse,

Danke für die Erklärungen und Danke an euch die mir helfen wollten.
Dann mache ich es mit Frorm.Hide - so läuft es dann auch im Hintergrund.

Gruß Frank
DL3AD
 
Beiträge: 300
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.6.4 FPC 3.0.2) und Debian 8 (L 1.6.4 FPC 3.0.2) | 
CPU-Target: 32Bit
Nach oben

Beitragvon Mathias » 29. Okt 2017, 16:28 Re: Programm ohne GUI

Hilfreich währe wenn jemand es mal anhand meines vorgegebenen GUI Beispieles macht.

Das sieht dann so aus:
Code: Alles auswählen
program Project1;
uses
  Crt,  blcksock;
 
type
  TMyUDP = class(TObject)
  private
    playsound1: Tplaysound;
  public
    //    playsound1: Tplaysound;
    procedure Check;
    procedure InitSocket;
    procedure DeInitSocket;
  end;
 
var
  UDPResiveSocket: TUDPBlockSocket;
 
  procedure TMyUDP.Check;
  var
    UDPRx: string;
  begin
    UDPRx := UDPResiveSocket.RecvPacket(50);
    if UDPRx <> '' then begin
      WriteLn('>' + UDPRx);
      //      playsound1.SoundFile := 'post.wav';
      //      playsound1.Execute;
    end;
  end;
 
  //UDP Socket erzeugen
  procedure TMyUDP.InitSocket;
  begin
    if UDPResiveSocket <> nil then begin
      DeInitSocket;
    end;
 
    UDPResiveSocket := TUDPBlockSocket.Create;
    UDPResiveSocket.CreateSocket;
    UDPResiveSocket.Bind('192.168.2.116', '10001');
  end;
 
  //UDP Socket freigeben
  procedure TMyUDP.DeInitSocket;
  begin
    UDPResiveSocket.CloseSocket;
    UDPResiveSocket.Free;
    UDPResiveSocket := nil;
  end;
 
var
  MyUPD: TMyUDP;
  ch: char;
 
begin
  MyUPD := TMyUDP.Create;
  MyUPD.InitSocket;
  WriteLn('[ESC]= beenden');
  repeat
    MyUPD.Check;
    if KeyPressed then begin
      ch := ReadKey;
    end;
  until ch = #27;
  MyUPD.DeInitSocket;
  MyUPD.Free;
end.

Auf die Classe könnte man auch noch verzichten und einfache Proceduren machen.
Das Tplaysound müsstes du noch einbauen, bei mi fehlt diese Komponente.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3201
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon wp_xyz » 29. Okt 2017, 16:40 Re: Programm ohne GUI

Soner hat geschrieben:Das einzige was hier stört is uplaysound-Unit. Das habe ich ja als Kommentar geschrieben.

Aber das Ding braucht doch keine LCL. Da sind nur ein paar Units, die standardmäßig eingebunden aber nicht benötigt werden. Und 1x ShowMessage und die Aboutbox.

Im Anhang ist eine modifizierte uPlaySound, die in einem Konsolenprogramm läuft (Achtung: den Linux-Teil habe mir nicht angesehen - möglich, dass man da noch etwas anpassen muss). Das Programm mit das Package LazUtils einbinden. -- Ich werde mal dem Autor vorschlagen, die Komponente entsprechend abzuändern.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
wp_xyz
 
Beiträge: 2253
Registriert: 8. Apr 2011, 08:01

Beitragvon Mathias » 29. Okt 2017, 17:26 Re: Programm ohne GUI

Noch ein Hinweis zu folgendem Code. Wen dieser unter Linux in einem Datei-Manger gestartet wird, erscheint keine Konsole, obwohl dies im Hintergrund läuft.
Man kann es dann höchsten noch mit einem "Kill" Kommando oder was ähnlichem beenden,
Code: Alles auswählen
  WriteLn('[ESC]= beenden');
  repeat
    MyUPD.Check;
    if KeyPressed then begin
      ch := ReadKey;
    end;
  until ch = #27;
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3201
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

• Themenende •

Zurück zu Einsteigerfragen



Wer ist online?

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

porpoises-institution
accuracy-worried