Objekte und andere Probleme (Beispiel App / Code)

Für Fragen von Einsteigern und Programmieranfängern...
Rhyt
Beiträge: 70
Registriert: Mo 28. Nov 2022, 20:22

Objekte und andere Probleme (Beispiel App / Code)

Beitrag von Rhyt »

Hallo,
ich versuche mir gerade etwas Objektorientiere Programmierung anzueignen. Hab dazu auch ein kleines Programm geschrieben das ein Rechteck Zeichnet das man bewegen kann und durch einen Timer sich auch selbst bewegt. Ich hab auch versucht ein Property einzubauen ( wobei mir nachdem ich das gemacht habe nicht ganz klar ist weshalb man sowas braucht, wenn man über public Variablen direkt einen Wert ändern kann.. ich hab es wohl noch nicht ganz verstanden).
Bei den Labels und ihrer Kolorierung habe ich auch noch meine Schwierigkeiten, da ich es nicht hinbekomme eine Procedure zu schreiben die allgemeingültig ist für beide Labels um diese Farben dann zu ändern. Eventuell kann mir jemand da einen Tipp geben.

Das gezeichnete Grid reagiert auch nicht wirklich auf das ändern der Fenstergröße (in Windows) unter Linux wenn ich QT nutze reagiert es wie gewünscht. Weiß allerdings auch nicht wo ich ansetzen muss.

Mag sich jemand das gebastelte mal anschauen und Verbesserungsvorschläge mir unterbreiten?

Bild


vielen Dank schonmal
Dateianhänge
BlockMovewithRecord V 2.zip
(490.5 KiB) 32-mal heruntergeladen
Zuletzt geändert von Rhyt am Di 29. Nov 2022, 11:10, insgesamt 3-mal geändert.

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Objekte und andere Probleme (Beispiel App / Code)

Beitrag von kupferstecher »

Rhyt hat geschrieben:
Mo 28. Nov 2022, 20:34
Bei den Labels und ihrer Kolorierung habe ich auch noch meine Schwierigkeiten, da ich es nicht hinbekomme eine Procedure zu schreiben die allgemeingültig ist für beide Labels um diese Farben dann zu ändern.
Deinen Code hab ich mir jetzt nicht angeschaut, lieber hier hochladen wie extern.
Also ganz allgemein: Das Objekt Label ist eine Klasseninstanz, die Variable, die das Label enthält ist tatsächlich eine Referenz auf das Objekt. In anderen Worten, in der Variablen steht nur die Speicheradresse des Objekts und beim Zuweisen an eine andere Variable oder bei der Übergabe als Funktionsparameter wird nur die Adresse übergeben, das eigentliche Objekt bleibt das Selbe. Farbe ändern:

Code: Alles auswählen

Procedure SetLabelColorToRed(aLabel: TLabel);
begin
 aLabel.Color:= clRed;
 aLabel.Font.Color:= clWhite;
end;
Benutzung:

Code: Alles auswählen

SetLabelColorToRed(Label1);
SetLabelColorToRed(Form1.Label1); //Wenn Aufruf von außerhalb der Form

Rhyt
Beiträge: 70
Registriert: Mo 28. Nov 2022, 20:22

Re: Objekte und andere Probleme (Beispiel App / Code)

Beitrag von Rhyt »

Danke dir, werde ich mal versuchen :)

Rhyt
Beiträge: 70
Registriert: Mo 28. Nov 2022, 20:22

Re: Objekte und andere Probleme (Beispiel App / Code)

Beitrag von Rhyt »

hab grad das Grid mal in der Delphi Community Edition ausprobiert, dort zeichnet es sich bei jedem vergrößern und verkleinern des Fensters korrekt neu ohne Probleme. Hat jemand eventuell jemand eine Ahnung warum das nur unter Windows in Lazarus nicht gescheit funktioniert? Und wie man das Problem beheben kann?

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Objekte und andere Probleme (Beispiel App / Code)

Beitrag von kupferstecher »

Habs mir gerade mal angeschaut, dein Programm vertraut auf die Canvas-Größe zum Zeichen des Grids. Es scheint, dass beim Verkleinern der Form der Canvas im Hintergrund nicht mitverkleinert wird. Beim Vergrößern wird er aber nachgezogen. Kann sein (muss aber nicht), dass das eine absichtliche Optimierung ist um Speicheroperationen zu reduzieren.
Eine Abhilfe wäre statt nur den Canvas an draw_grid zu übergeben das ganze Control und daraus dann die Höhe und Breite zu entnehmen.
Wenn es nicht nur für Forms gehen soll, würde sich TCustomControl als gemeinsamer Vorfahre anbieten, dort steckt wohl der Canvas drin, auf dem dann ja gearbeitet wird. Ein TPanel bspw. ist auch von TCustomControl abgeleitet.
Die Funktionsparameter lauten dann:

Code: Alles auswählen

procedure draw_grid(col, col_width, rows, row_height: integer; aControl: TCustomControl);
[Edit: Aufruf dann per draw_grid(0,0,0,0,Form1);]

In der Dokumentation ist die Vererbungshierarchie abgebildet.
https://lazarus-ccr.sourceforge.io/docs ... tform.html

Oben rechts auf der Seite steht auch jeweils die Unit der Komponente (die man ggf. in uses einbinden muss).


Noch ein Tipp fürs Debugging:
Man kann unter Win neben der Form auch ein Konsolenfenster anzeigen lassen, um sich mit WriteLn dann Werte auszugeben. Dazu in der lpr-Datei ganz oben die Zeile

Code: Alles auswählen

{$APPTYPE CONSOLE} 
einfügen. Entgegen der Intuition bleibt es trotzdem ein GUI-Programm, nur mit zusätzlichem Konsolenfenster.

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Objekte und andere Probleme (Beispiel App / Code)

Beitrag von siro »

coole Sache, allein vom mitlesen lernt man immer wieder dazu.
@kupferstecher: Vielen Dank für diese Info
Ich habe das grade mal ausprobiert.

Also oben in der Menüleiste "Projekt" anklicken
dann im Pulldown Menü die unterste Zeile den Menüpunkt
.lpr-Datei anzeigen
anklicken

Es öffnet sich die entsprechende Datei:

Code: Alles auswählen

{$APPTYPE CONSOLE}   // <---- HIER muss die entsprechende Zeile rein !!!

program Project1;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  {$IFDEF HASAMIGA}
  athreads,
  {$ENDIF}
  Interfaces, // this includes the LCL widgetset
  Forms, unit1
  { you can add units after this };

{$R *.res}

begin
  RequireDerivedFormResource:=True;
  Application.Scaled:=True;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
          
-----------------------------
Ein kleines Testprogramm:

Code: Alles auswählen

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs;

type

  { TForm1 }

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  // folgende Ausgabe erscheint dann in einem Konsolenfenster
  Writeln('ich befinde mich in der Procedure FormCreate');
end;

end.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
theo
Beiträge: 10468
Registriert: Mo 11. Sep 2006, 19:01

Re: Objekte und andere Probleme (Beispiel App / Code)

Beitrag von theo »

Auch auf Linux tauglich ist:
Ansicht -> Debuggerfenster -> Console In/Ouput.
Läuft aber nur mit eingeschaltetem Debugger.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Objekte und andere Probleme (Beispiel App / Code)

Beitrag von af0815 »

Windows: (Nicht Linux)
Projekt Optionen -> Compiler Options -> Config und Target, dort das Häckchen bei Win32 gui application rausnehmen und schon ist die Konsole da.

Hat den großen Vorteil, das man das ganze über die Build Modes steuern kann und nicht das gefrickel im Source braucht.

Wenn man dann noch den LazLogger verwendet, kann man vieles sichtbar machen und wenn man die Konsole abschaltet passiert auch nichts.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Objekte und andere Probleme (Beispiel App / Code)

Beitrag von Mathias »

@Rhyt

Code: Alles auswählen

    property isTouching: boolean read touched write touched;
    property setColor: TColor read color write color;   
Noch ein Tipp, es empfiehlt sich folgende Regel bei Propertys einzuhalten.
Den privaten Variablem immer ein "F" voranstellen.
Und das Setxxx immer für Setter verwenden.
Das würde in deinem Fall dann so aussehen:

Code: Alles auswählen

    property isTouching: boolean read FisTouching write FisTouching;
    property Color: TColor read FColor write FColor;   
Mit Setter und Getter würde es dann so aussehen:

Code: Alles auswählen

   property Color: TColor read GetColor write SetColor;  
   ...
   procedure TBlock.SetColor(AColor: TColor);
   begin
     FColor := AColor;
   end;
   
   function TBlock.GetColor: TColor;
   begin
     Result := FColor;
   end;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Rhyt
Beiträge: 70
Registriert: Mo 28. Nov 2022, 20:22

Re: Objekte und andere Probleme (Beispiel App / Code)

Beitrag von Rhyt »

Holla :) ich hab schon fast gedacht der Post verläuft sich im Sand. Danke für die Antworten! Die werden morgen früh gleich alle in Ruhe durchgearbeitet.

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Objekte und andere Probleme (Beispiel App / Code)

Beitrag von siro »

@af0815: supi, ja da geht auch, grad getestet.
Danke

es bleibt trotzdem eine grafische Anwendung, das muss man wissen, das hätte ich nicht gedacht...
Konsolen_Haken.jpg
Konsolen_Haken.jpg (89.49 KiB) 853 mal betrachtet
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Objekte und andere Probleme (Beispiel App / Code)

Beitrag von af0815 »

Kleiner Hinweis, man sollte sich angewöhnen mit Erstellmodis zu arbeiten
Screenshot 2022-12-01 065855_1.jpg
Screenshot 2022-12-01 065855_1.jpg (38.29 KiB) 849 mal betrachtet
Da oben sollte zumindest Debug oder Release stehen. Erstellt man die Modis so hat an den Vorteil, das man im Release andere Voreinstellungen haben kann, wie eben das Win32 GUI Häkchen. Im Debugmodus habe ich alle Prüfungen ein, im Release normalerweise fast alles aus. Die Modis kann man sich in der Caption von Lazarus auch anzeigen lassen, damit sieht man auf einem Blick für welchen Modus gerade kompiliert wird.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Objekte und andere Probleme (Beispiel App / Code)

Beitrag von Warf »

Rhyt hat geschrieben:
Mo 28. Nov 2022, 20:34
Ich hab auch versucht ein Property einzubauen ( wobei mir nachdem ich das gemacht habe nicht ganz klar ist weshalb man sowas braucht, wenn man über public Variablen direkt einen Wert ändern kann.. ich hab es wohl noch nicht ganz verstanden).
Um die Frage mal zu beantworten, öffentliche Variablen erlauben keine Zugriffskontrolle, wenn du eine Öffentliche Variable hast kannst du damit machen was du willst. Properties hingegen können Zugriffskontrollen beinhalten. Das einfachste hier ist das beschränken auf nur lesenden oder schreibenden zugriff:

Code: Alles auswählen

property ReadWrite: Integer read FMyVar write FMyVar; // Verhält sich im grunde wie eine variable
property ReadOnly: Integer read FMyVar; // Damit kann man eine Variable auslesen aber nicht schreiben
property WriteOnly: Integer write FMyVar; // Damit kann man eine Variable verändern aber nicht auslesen
Aber du kannst sogar auch beinflussen wie die Werte geschrieben/Gelesen werden

Code: Alles auswählen

 // Annahme TCircle klasse mit nem Radius
property Diameter: Double read GetDiameter write SetDiameter;

function TCircle.GetDiameter: Double;
begin
  Result := 2 * Radius;
end;

procedure TCircle.SetDiameter(AValue: Double);
begin
  Radius := AValue / 2;
end;
Hier wird eine Property erstellt die so gar nicht als variable existiert, sondern immer aus anderen werten Umgerechnet wird.

Man kann natürlich auch properties benutzen um gewisse Anforderungen umzusetzen:

Code: Alles auswählen

property MyValue: Integer read FMyValue write SetMyValue;

procedure SetMyValue(AValue: Integer);
begin
  if AValue < 0 then
    raise Exception.Create('Negative values are not allowed');
  FMyValue := AValue;
end;
Langer rede kurzer Sinn, properties sind viel flexibler als einfach öffentliche variablen. Selbst in dem Fall indem man einfach von den variablen liest und schreibt, sollte man properties benutzen, denn falls man in Zukunft den Zugriff beschränken will, kann man das, wenn die Properties eh schon existieren, mit nur minimalen Änderungen erreichen.
Zum Vergleich, wenn man immer direkt auf die Variablen direkt zugreift muss man zum hinzufügen von Zugriffskontrolle die Variablen umbennenen und eine property nachträglich hinzufügen und dann muss man überall wo diese Variable benutzt wurde schauen ob da jetzt nicht was kaptutt geht

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Objekte und andere Probleme (Beispiel App / Code)

Beitrag von af0815 »

Es gibt bei den Properties noch weitere Besonderheiten, wenn man die Serialisiert, dann werden published deklarierte Properties auch gespeichert bzw. rückgelesen. Das geht soweit ich mich erinnere, dann über RTTI (RunTimeTypeInformation).

Es hat schon Vorteile wenn man Properties verwendet, gewöhnen muss man sich daran.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Rhyt
Beiträge: 70
Registriert: Mo 28. Nov 2022, 20:22

Re: Objekte und andere Probleme (Beispiel App / Code)

Beitrag von Rhyt »

@kupferstecher
Danke für den Tipp mit dem TCustomControl, da wäre ich im Leben nie drauf gekommen. Jetzt funktioniert das :)

Woher kommt das mit dem F vor den Variablen bei den Privates ? :) für was steht das ?

@kupferstecher und af0815, danke für den Trick mit der Konsole / Terminal. Das habe ich schon länger gesucht :) kannte das aus meinen Objective C (15 Jahre her gefühlt, und alles verlernt) Zeiten noch und hab das vermisst.


Ich hab mal eine neue Version gebastelt. Und bekomme jetzt ein Heap Speicher Fehler beim beenden im Debug Modus. Kann damit noch nicht viel anfangen, da ich dachte das der Destructor in der Block klasse alles entfernt. hm eventuell hat jemand ja einen Anhaltspunkt was da schief läuft.
Dateianhänge
Lazarus_Delphi_C#_Demo - V2.zip
(492.47 KiB) 23-mal heruntergeladen

Antworten