Forum: PC-Programmierung Kann mir jemand bei Lazarus weiter helfen? (Delphi, Pascal.)


von Markus J. (dmant)


Lesenswert?

Hallo,

ich habe eine Form....

Diese öffnet sich. Nach dem öffnen wird ein Frame angezeigt. Super.

Mit diesem Frame startet ein Timer der eine ProgressBar füllt. Sobald 
die ProgressBar gefüllt ist soll sich der Frame wieder schließen und ein 
nächster öffnen.

Ich bin soweit, das sich das Frame nach dem ablauf des Timer schließt, 
jedoch dann passiert nichts mehr.

gui.pas
1
unit gui;
2
3
{$mode objfpc}{$H+}
4
5
interface
6
7
uses
8
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
9
  boot, Unit1;
10
11
type
12
13
  { TForm1 }
14
15
  TForm1 = class(TForm)
16
  Frame2_1: TFrame2;
17
18
  procedure FormCreate(Sender: TObject);
19
20
  private
21
22
  public
23
    Frame: TFrame;
24
  end;
25
26
var
27
  Form1: TForm1;
28
29
implementation
30
31
{$R *.lfm}
32
33
{ TForm1 }
34
35
procedure TForm1.FormCreate(Sender: TObject);
36
begin
37
  Frame := TFrame1.Create(Self);
38
  Frame.Parent:= Frame2_1;
39
end;
40
41
end.

boot.pas
1
unit boot;
2
3
{$mode objfpc}{$H+}
4
5
interface
6
7
uses
8
  Classes, SysUtils, Forms, Controls, StdCtrls, ExtCtrls, ComCtrls;
9
10
type
11
12
  { TFrame1 }
13
14
  TFrame1 = class(TFrame)
15
16
  Image1: TImage;
17
  ProgressBar1: TProgressBar;
18
  Timer1: TTimer;
19
  procedure Timer1Timer(Sender: TObject);
20
21
  private
22
    MyObj: TObject;
23
    progressInt : Integer;
24
  public
25
    constructor Create(TheOwner: TComponent); override;
26
    destructor Destroy; override;
27
  end;
28
29
30
implementation
31
32
{$R *.lfm}
33
34
{ TFrame1 }
35
36
destructor TFrame1.Destroy;
37
  begin
38
    MyObj.Free;
39
    inherited Destroy;
40
  end;
41
42
procedure TFrame1.Timer1Timer(Sender: TObject);
43
begin
44
     progressInt:= progressInt + 20;
45
     if progressInt=120 then
46
     begin
47
       Destroy;
48
     end;
49
     ProgressBar1.Position:= progressInt;
50
51
end;
52
53
constructor TFrame1.Create(TheOwner: TComponent);
54
  begin
55
    inherited Create(TheOwner);
56
    MyObj := TObject.Create;
57
  end;
58
59
end.

Wie kriege ich jetzt das ich danach wieder auf den Frame einen anderen 
Frame anzeigen kann?

Ich hoffe mir kann der ein oder andere helfen.
Vielen dank.

von MiWi (Gast)


Lesenswert?

Markus J. schrieb:
> procedure TFrame1.Timer1Timer(Sender: TObject);
> begin
>      progressInt:= progressInt + 20;
>      if progressInt=120 then
>      begin
>        Destroy;
>      end;
>      ProgressBar1.Position:= progressInt;
>
> end;

Der Timer gehört zum Frame. Mit 'Destroy' räumst du das Fenster (und 
alles was dazu gehört) ab. Wer soll jetzt noch was Anzeigendes machen?

Du könntest vor 'Destroy' ein neues Fenster erzeugen, oder - der 
Klassiker - ein bereits erzeugtes Fenster anzeigen lassen.

Hier ist das erklärt, hoffe ich:
https://wiki.freepascal.org/Form_Tutorial/de

von Sebastian S. (amateur)


Lesenswert?

Einen großen Lappen nehmen und das Fenster "putzen".

Es ist kein Problem alle Elemente "abzuschalten" und das Fenster neu 
garnieren.
Alternativ kannst Du auch zwei Panele in Fenstergröße platzieren und 
diese einfach Wechseln. Funktioniert (optisch) so ähnlich wie 
Tabulatoren, bei denen allerdings die Steuerelemente - gewünscht - 
sichtbar bleiben.
Vergiss nicht das Panel zu deaktivieren und damit die platzierten 
Steuerelemente, sonst sind letztere noch via Tab zu erreichen.

Es ist auch möglich das ursprüngliche Aussehen wieder herzustellen, 
indem das erste Panel wieder in den Vordergrund geholt wird und das 
zweite passiv gemacht wird.
Oder auch nicht.

von MiWi (Gast)


Lesenswert?

Sebastian S. schrieb:
> Es ist kein Problem alle Elemente "abzuschalten" und das Fenster neu
> garnieren.

Na ja, die Fenster werden in der IDE zusammen geclicked. Und man 
'designed' sich die Fenster, die man haben will. Zur Laufzeit wird dann 
einfach hin und her geschaltet oder auch mehrere gleichzeitig zur 
Anzeige gebracht. Wenn du Angst um deinen Speicher hast, erzeugst du die 
- in Delphi/Lazarus immer dynamsichen - Fenster erst zur Laufzeit.

Aber die einzelnen Elemente zur Laufzeit aufs Fenster zu poppen oder 
mehrere alternative Panel/Frames/sonstige Container übereinander zu 
designen ist absoluter Murks.

@(amateur): Aber warum einfach, wenn 's auch ...

von Markus J. (dmant)


Lesenswert?

Ok...

Also ich habe es jetzt schon ein Stückchen weiter...

Also ich habe nun zwei frames... Die ich "hin und her" bzw ein und 
ausschalten kann.

Für mich ist diese Sprache... Ähm ja... Einfach nur verwirrend... Und 
naja..

Die gui klickt man sich zusammen.. Das finde ich super... Ich klicke mir 
einfach jede Ansicht zusammen und lasse diese dann ein/ausblenden...

Das zumindest geht...

Aber jetzt geht es an die dynamischen Daten....

Wenn ich jetzt z.b.

ein "echo 30“ | sudo tee sys...../brigthness

Machen will...

Also ich habe eine Trackbar... Und bei der Änderung... Ja... Alao

SysUtils.ExecuteProzess(......)

Dann kommt das er den Befehl nicht ausführen kann.. Auf der Bash 
(gleicher user) klappt das aber...

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

Markus J. schrieb:
> Aber jetzt geht es an die dynamischen Daten....
> Wenn ich jetzt z.b.
> ein "echo 30“ | sudo tee sys...../brigthness
> Machen will...
> Also ich habe eine Trackbar... Und bei der Änderung... Ja... Alao
> SysUtils.ExecuteProzess(......)
> Dann kommt das er den Befehl nicht ausführen kann.. Auf der Bash
> (gleicher user) klappt das aber...

"dynamisches Raten" beschreibt dieses Gedanken-Gestotter perfekt

Was willst du jetzt mit dem sudo-Command in der Pascal-GUI?

: Bearbeitet durch User
von Markus J. (dmant)


Lesenswert?

Also...

Ich habe eine Trackbar... Die gui läuft auf einem Raspberry mit dem 
offiziellen 7 Zoll TFT.

So..wenn ich nun die Trackbar bewege soll diese bei einem change den 
Befehl ausführen. Diesen Befehl ändert die Display Helligkeit.

Ich habe mir jetzt mal ein testscript geschrieben...
1
#!/bin/bash
2
3
echo 20 | sudo tee /sys/class/backlight/rpi_backlight/brightness

abgelegt unter

/usr/local/bin/set_brigth

ausführbar gemacht.. Getestet... Klappt...

So...

SysUtils.Prozess......

klappt auch im delphi

Script geändert
1
#!/bin/bash
2
3
echo ${1} | sudo tee /sys/class/backlight/rpi_backlight/brightness

getestet mit

set_bright n

klappt. (n = Wert zwischen 0-255)

SysUtils.Pro.....'set_brigth ' + TrackBar1.Position...

Sobald ich die Trackbar bewege kommt ein error von wegen

Set_brigth n (also da steht dann die Zahl) kann er nicht ausführen....

von Markus J. (dmant)


Angehängte Dateien:

Lesenswert?

Hier mal ein Bild davon....

Da hab ich noch nen anderen Pfad gehabt... Aber ohne args geht es.. Mit 
args geht es nicht...


Hier noch der Code
1
unit home;
2
3
{$mode objfpc}{$H+}
4
5
interface
6
7
uses
8
  Classes, SysUtils, Forms, Controls, ExtCtrls, StdCtrls, ComCtrls;
9
var
10
  year, month, day, hr, min, sec, ms: Word;
11
type
12
13
  { TFrame3 }
14
15
  TFrame3 = class(TFrame)
16
    Image1: TImage;
17
    Image2: TImage;
18
    StaticText1: TStaticText;
19
    StaticText2: TStaticText;
20
    Timer1: TTimer;
21
    TrackBar1: TTrackBar;
22
    procedure Timer1Timer(Sender: TObject);
23
    procedure TrackBar1Change(Sender: TObject);
24
  private
25
    MyObj: TObject;
26
  public
27
    constructor Create(TheOwner: TComponent); override;
28
    destructor Destroy; override;
29
  end;
30
31
implementation
32
33
uses
34
  gui;
35
36
{$R *.lfm}
37
38
{ TFrame3 }
39
40
destructor TFrame3.Destroy;
41
  begin
42
    MyObj.Free;
43
    inherited Destroy;
44
  end;
45
46
procedure TFrame3.Timer1Timer(Sender: TObject);
47
begin
48
  DecodeTime(Time,hr, min, sec, ms);
49
  StaticText1.Caption := format('%.2d',[hr]) + ':' + format('%.2d', [min]);
50
  DecodeDate(Date,year,month,day);
51
  StaticText2.Caption := format('%.2d',[day]) + '.' + format('%.2d', [month]) + '.' + format('%.2d', [year]);
52
53
end;
54
55
procedure TFrame3.TrackBar1Change(Sender: TObject);
56
begin
57
  SysUtils.ExecuteProcess('/home/pihome/scripts/brightness ' + IntToStr(TrackBar1.Position), '', []);
58
end;
59
60
constructor TFrame3.Create(TheOwner: TComponent);
61
  begin
62
    inherited Create(TheOwner);
63
    MyObj := TObject.Create;
64
    DecodeTime(Time,hr, min, sec, ms);
65
    StaticText1.Caption := format('%.2d',[hr]) + ':' + format('%.2d', [min]);
66
    DecodeDate(Date,year,month,day);
67
    StaticText2.Caption := format('%.2d',[day]) + '.' + format('%.2d', [month]) + '.' + format('%.2d', [year]);
68
  end;
69
70
end.

Und der Fehler passiert hierdurch:
1
procedure TFrame3.TrackBar1Change(Sender: TObject);
2
begin
3
  SysUtils.ExecuteProcess('/home/pihome/scripts/brightness ' + IntToStr(TrackBar1.Position), '', []);
4
end;

: Bearbeitet durch User
von HeikoG (Gast)


Lesenswert?

Markus J. schrieb:
> SysUtils.ExecuteProcess('/home/pihome/scripts/brightness ' +
> IntToStr(TrackBar1.Position), '', []);

Error 127 meint Command not found.

SysUtils.ExecuteProcess erwartet Programm und Programmparameter in 
getrennten Parametern, also eher :

SysUtils.ExecuteProcess('/home/pihome/scripts/brightness',IntToStr(Track 
Bar1.Position),  []);

Evtl. ist es auch nicht möglich bash-scripte direkt auszuführen, dann 
evtl. explizit die Shell verwenden:

SysUtils.ExecuteProcess('/bin/bash/','/home/pihome/scripts/brightness ' 
+ IntToStr(TrackBar1.Position), []);

von Markus J. (dmant)


Lesenswert?

ne...

dann sagt er failed execute /bin/bash

von HeikoG (Gast)


Lesenswert?

Die Shell sollte aber da liegen, sonst wäre das Script mit dem shebang

#!/bin/bash

ja auch falsch. Ich hatte da aber einen Schreibfehler, da war ein Slash 
zuviel:

SysUtils.ExecuteProcess('/bin/bash','/home/pihome/scripts/brightness '
+ IntToStr(TrackBar1.Position), []);

von Markus J. (dmant)


Lesenswert?

So....

also ich habe noch mal ein wenig gegoogeld und herauf gefunden das man 
dafür TProcess nutzen soll..

gemacht.. getan...
1
procedure TFrame3.TrackBar1Change(Sender: TObject);
2
begin
3
  Process1.Parameters.Add(IntToStr(TrackBar1.Position));
4
  Process1.Execute;
5
end;

nun wird der befehl ausgeführt... perfekt.. jedoch...

Der Returnwert von der TrackBar ist immer 17... ob ich ändere oder 
nicht.. es ist immer 17...

von W.S. (Gast)


Lesenswert?

Markus J. schrieb:
> Aber jetzt geht es an die dynamischen Daten....
> Wenn ich jetzt z.b.
> ein "echo 30“ | sudo tee sys...../brigthness
> Machen will...

Ähemm.. und wozu willst du überhaupt eine Shell zum Ausführen eines 
Shellscripts ausführen lassen?

Kannst du die Displayhelligkeit denn nicht ganz einfach innerhalb deines 
Programms einstellen? Fehlt dir dazu irgend etwas geeignetes im API 
deines OS?

und nein, einen Rat, wie du es besser machen kannst, kann ich dir nicht 
geben, Linux ist nicht mein Ding. Mir fällt nur auf, daß du für sowas 
überhaupt ein Shellscript benutzen willst.

W.S.

von Dirk K. (merciless)


Lesenswert?

Vielleicht hilft das weiter: 
https://forum.lazarus.freepascal.org/index.php?topic=24900.0

merciless

von Markus J. (dmant)


Lesenswert?

Also ich kriege den Befehl ausgeführt... Aber keine args... Und eben 
immer 17...

von Markus J. (dmant)


Lesenswert?

Sooo...

also es klappt nun
1
procedure TFrame3.TrackBar1Change(Sender: TObject);
2
begin
3
  StaticText3.Caption:=IntToStr(TrackBar1.Position);
4
  Process1.CommandLine:='/home/pihome/scripts/brightness ' + IntToStr(TrackBar1.Position);
5
  Process1.Execute;
6
end;

von Hmmm (Gast)


Lesenswert?

Markus J. schrieb:
> #!/bin/bash

Mal als allgemeiner Hinweis: Das ist eine eklige Linux-Unart. Sofern man 
nicht tatsächlich reine Bash-Features verwendet, gehört da /bin/sh hin, 
denn es gibt nicht auf jedem System eine Bash.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.