TShape Farbverlauf

Für Fragen von Einsteigern und Programmieranfängern...
Andy Nightingale
Beiträge: 245
Registriert: Mo 13. Jan 2025, 12:11

TShape Farbverlauf

Beitrag von Andy Nightingale »

Hallo Leute
wie bekomme ich in einem TShape einen Farbverlauf hin? Also z.B. von Dunkelgrau nach Hellgrau?Grüße

wp_xyz
Beiträge: 5163
Registriert: Fr 8. Apr 2011, 09:01

Re: TShape Farbverlauf

Beitrag von wp_xyz »

Es gibt zwar ein OnPaint-Event, aber das füllt die komplette Fläche mit dem Farbverlauf aus und übermalt die Form. Eine allgemeine Lösung erscheint mir relativ kompliziert. Um welche Form (Rechteck, Kreis, ...) geht es denn?

Andy Nightingale
Beiträge: 245
Registriert: Mo 13. Jan 2025, 12:11

Re: TShape Farbverlauf

Beitrag von Andy Nightingale »

Es geht um ein Rechteck. Oder gibt es eine andere Lösung? Grüße

wp_xyz
Beiträge: 5163
Registriert: Fr 8. Apr 2011, 09:01

Re: TShape Farbverlauf

Beitrag von wp_xyz »

Ein Rechteck ist einfach - siehe Anhang. Bei den anderen Formen (Property Shape) müsste man das Clipping hinkriegen, das viele Einzelschritte benötigt.
Dateianhänge
shape_gradient.png
shape_gradient.png (5.22 KiB) 2523 mal betrachtet
shape_gradient.zip
(1.98 KiB) 119-mal heruntergeladen

Andy Nightingale
Beiträge: 245
Registriert: Mo 13. Jan 2025, 12:11

Re: TShape Farbverlauf

Beitrag von Andy Nightingale »

Hallo WP,

krass. Genau das meinte ich. Aber sag mal unter uns. Wie kommt man auf so etwas?:
const
START_COLOR = clGray;
END_COLOR = clSilver;
var
R: TRect;
begin
R := Rect(0, 0, Shape1.Width, Shape1.Height);
Shape1.Canvas.GradientFill(R, START_COLOR, END_COLOR, gdHorizontal);
Shape1.Canvas.Brush.Style := bsClear;
Shape1.Canvas.Pen.Assign(Shape1.Pen);
Shape1.Canvas.Rectangle(R);
Das würde mich interessieren,.-ganz doll. Danke und Grüße

kirchfritz
Beiträge: 219
Registriert: Mo 3. Jan 2011, 13:34
OS, Lazarus, FPC: Win11 (L 3.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Nürnberg

Re: TShape Farbverlauf

Beitrag von kirchfritz »

Mal eine blöde Frage: Warum nutzt Du anstelle eines TShape-Objects nicht ein TBCPanel? Das ist auch eine rechteckige Fläche und dort gibt es in der Background-Property die Möglichkeit einen Gradientenverlauf zu spezifizieren.

Andy Nightingale
Beiträge: 245
Registriert: Mo 13. Jan 2025, 12:11

Re: TShape Farbverlauf

Beitrag von Andy Nightingale »

kirchfritz hat geschrieben: Mi 14. Mai 2025, 20:48 Mal eine blöde Frage: Warum nutzt Du anstelle eines TShape-Objects nicht ein TBCPanel? Das ist auch eine rechteckige Fläche und dort gibt es in der Background-Property die Möglichkeit einen Gradientenverlauf zu spezifizieren.
Auch mal ne blöde Frage: wie machst du das? Habs getestet. Geht nicht wirklich.

wp_xyz
Beiträge: 5163
Registriert: Fr 8. Apr 2011, 09:01

Re: TShape Farbverlauf

Beitrag von wp_xyz »

Andy Nightingale hat geschrieben: Mi 14. Mai 2025, 20:26 Wie kommt man auf so etwas?
GradientFill ist eine Methode des Canvas. Wenn man das weiß, ist der Code naheliegend.

https://dsiders.gitlab.io/lazdocsnext/l ... tfill.html

Andy Nightingale
Beiträge: 245
Registriert: Mo 13. Jan 2025, 12:11

Re: TShape Farbverlauf

Beitrag von Andy Nightingale »

kirchfritz hat geschrieben: Mi 14. Mai 2025, 20:48 Mal eine blöde Frage: Warum nutzt Du anstelle eines TShape-Objects nicht ein TBCPanel? Das ist auch eine rechteckige Fläche und dort gibt es in der Background-Property die Möglichkeit einen Gradientenverlauf zu spezifizieren.
Hallo Kirchfritz.- könntest du mir ein kleines Beispiel machen. Das wäre super. Danke

Andy Nightingale
Beiträge: 245
Registriert: Mo 13. Jan 2025, 12:11

Re: TShape Farbverlauf

Beitrag von Andy Nightingale »

wp_xyz hat geschrieben: Mi 14. Mai 2025, 22:38
Andy Nightingale hat geschrieben: Mi 14. Mai 2025, 20:26 Wie kommt man auf so etwas?
GradientFill ist eine Methode des Canvas. Wenn man das weiß, ist der Code naheliegend.

https://dsiders.gitlab.io/lazdocsnext/l ... tfill.html
Mir ist da nichts naheliegend....muß das nochmal genauer ansehen. Aber ich denke in ein paar Jahren geht es mir hoffentlich auch so. :D

wp_xyz
Beiträge: 5163
Registriert: Fr 8. Apr 2011, 09:01

Re: TShape Farbverlauf

Beitrag von wp_xyz »

Sorry, das sollte nicht arrogant klingen, sondern nur ausdrücken, dass da nichts besonderes dahinter steckt. Nur muss man halt die Grundbegriffe in diesem Zusammenhang kennen.

Ohne jetzt ein Tutorial für Graphik mit der LCL schreiben zu wollen, nur so viel:
  • Der Canvas ("Leinwand") ist die Arbeitsfläche für Zeichenausgaben. Die meisten Controls haben einen Canvas, aber wenn gerade keine Ausgabe läuft, ist das Ding nicht zuverlässig benutzbar. Daher nur im OnPaint-ereignis zeichnen!
  • Zu einer "Leinwand" gehört ein Pinsel (Brush) zum Füllen von Flächen und ein Stift (Pen) zum Zeichnen von Umrissen.
  • Beide haben eine Farbe (Canvas.Brush.Color, Canvas.PenColor)
  • Die Eigenschaft Style bestimmt beim Brush, wie die Fläche gefüllt wird: mit konstanter Farbe (bsSolid), mit Muster (bsHorizontal, bsVertical, ...), mit Bild (bsImage,) oder gar nicht (bsClear)
  • Beim Pen analog: psSolid (durchgezogenen Linie), psDash (gestrichelt), psDot (gepunktelt) ..., psClear (keine Linie). Der hat auch noch einen Parameter für die Breite in Pixeln (Width).
  • Der Canvas hat verschiedene Methoden z.B. zum Zeichnen von Figuren: Rectangle(links, oben, rechts, unten) zeichnet ein Rechteck mit Ecken an den genannten Koordinaten, Ellipse(...) eine in ein solches Rechteck eingepasste Ellipse, RoundRect ein Rechteck mit abgerundeten Ecken, Polygon ein Polygon mit gegebenen Eckpunkten, usw. Und eben auch GradientFill, was ein Rechteck mit einem Farbverlauf füllt.
  • Für jede dieser Operationen werden die vorher gesetzten Brush und Pen-Eigenschaften herangezogen.
Mein GradientFill-Code macht dann folgendes:

Code: Alles auswählen

const
  START_COLOR = clGray;
  END_COLOR = clSilver;
var
  R: TRect;
begin
  R := Rect(0, 0, Shape1.Width, Shape1.Height);
  Shape1.Canvas.GradientFill(R, START_COLOR, END_COLOR, gdHorizontal);
  Shape1.Canvas.Brush.Style := bsClear;
  Shape1.Canvas.Pen.Assign(Shape1.Pen);
  Shape1.Canvas.Rectangle(R); 
  • Der "const"-Bereich definiert die Anfangs- und Endfarben des Farbverlaufs; das könnte man auch direkt in den GradientFill-Aufruf schreiben, aber so muss man nicht in den Details des Codes suchen, wenn man die Farben ändern möchte. Geschmackssache...
  • Shape1.Canvas ist der Canvas der Shape-Komponente. Der existiert hier, weil das alles im OnPaint-Ereignis der Komponente aufgerufen wird.
  • Shape1.Canvas.GradientFill füllt das vorher definierte Rechteck R mit dem Farbverlauf, wobei die Farben zwsichen START_COLOR und END_COLOR in horizontaler Richtung (gdHorizontal) wechseln.
  • GradientFill zeichnet aber keinen Umriss für das Rechteck. Dafür will ich die Rectangle-Methode des Shape1.Canvas verwenden, nur füllt diese das Rechteck selbst wieder mit dem vorher eingestellten Brush, was den Farbverlauf übermalen würde. Um das zu verhindern setze ich den Brush.Style auf bsClear, also nichts füllen, nur den Umriss zeichnen., wofür die im Shape eingestellten Properties (Shape1.Pen) verwendet werden.
  • Alternativ könnte man auch zuerst das Rectangle zeichnen, dann das Rechteck um 1 pixel auf allen Seiten verkleinern und dann in dieses den Farbverlauf reinsetzen. Probier das doch mal als "Hausaufgabe".

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

Re: TShape Farbverlauf

Beitrag von theo »

Auch könnte man sich fragen, wozu überhaupt eine TShape.
TPaintBox würde vielleicht auch reichen für ein Rechteck.
Man kann natürlich auch direkt auf das Formular zeichnen.

Andy Nightingale
Beiträge: 245
Registriert: Mo 13. Jan 2025, 12:11

Re: TShape Farbverlauf

Beitrag von Andy Nightingale »

wp_xyz hat geschrieben: Do 15. Mai 2025, 14:07 Sorry, das sollte nicht arrogant klingen, sondern nur ausdrücken, dass da nichts besonderes dahinter steckt. Nur muss man halt die Grundbegriffe in diesem Zusammenhang kennen.

Ohne jetzt ein Tutorial für Graphik mit der LCL schreiben zu wollen, nur so viel:
  • Der Canvas ("Leinwand") ist die Arbeitsfläche für Zeichenausgaben. Die meisten Controls haben einen Canvas, aber wenn gerade keine Ausgabe läuft, ist das Ding nicht zuverlässig benutzbar. Daher nur im OnPaint-ereignis zeichnen!
  • Zu einer "Leinwand" gehört ein Pinsel (Brush) zum Füllen von Flächen und ein Stift (Pen) zum Zeichnen von Umrissen.
  • Beide haben eine Farbe (Canvas.Brush.Color, Canvas.PenColor)
  • Die Eigenschaft Style bestimmt beim Brush, wie die Fläche gefüllt wird: mit konstanter Farbe (bsSolid), mit Muster (bsHorizontal, bsVertical, ...), mit Bild (bsImage,) oder gar nicht (bsClear)
  • Beim Pen analog: psSolid (durchgezogenen Linie), psDash (gestrichelt), psDot (gepunktelt) ..., psClear (keine Linie). Der hat auch noch einen Parameter für die Breite in Pixeln (Width).
  • Der Canvas hat verschiedene Methoden z.B. zum Zeichnen von Figuren: Rectangle(links, oben, rechts, unten) zeichnet ein Rechteck mit Ecken an den genannten Koordinaten, Ellipse(...) eine in ein solches Rechteck eingepasste Ellipse, RoundRect ein Rechteck mit abgerundeten Ecken, Polygon ein Polygon mit gegebenen Eckpunkten, usw. Und eben auch GradientFill, was ein Rechteck mit einem Farbverlauf füllt.
  • Für jede dieser Operationen werden die vorher gesetzten Brush und Pen-Eigenschaften herangezogen.
Mein GradientFill-Code macht dann folgendes:

Code: Alles auswählen

const
  START_COLOR = clGray;
  END_COLOR = clSilver;
var
  R: TRect;
begin
  R := Rect(0, 0, Shape1.Width, Shape1.Height);
  Shape1.Canvas.GradientFill(R, START_COLOR, END_COLOR, gdHorizontal);
  Shape1.Canvas.Brush.Style := bsClear;
  Shape1.Canvas.Pen.Assign(Shape1.Pen);
  Shape1.Canvas.Rectangle(R); 
  • Der "const"-Bereich definiert die Anfangs- und Endfarben des Farbverlaufs; das könnte man auch direkt in den GradientFill-Aufruf schreiben, aber so muss man nicht in den Details des Codes suchen, wenn man die Farben ändern möchte. Geschmackssache...
  • Shape1.Canvas ist der Canvas der Shape-Komponente. Der existiert hier, weil das alles im OnPaint-Ereignis der Komponente aufgerufen wird.
  • Shape1.Canvas.GradientFill füllt das vorher definierte Rechteck R mit dem Farbverlauf, wobei die Farben zwsichen START_COLOR und END_COLOR in horizontaler Richtung (gdHorizontal) wechseln.
  • GradientFill zeichnet aber keinen Umriss für das Rechteck. Dafür will ich die Rectangle-Methode des Shape1.Canvas verwenden, nur füllt diese das Rechteck selbst wieder mit dem vorher eingestellten Brush, was den Farbverlauf übermalen würde. Um das zu verhindern setze ich den Brush.Style auf bsClear, also nichts füllen, nur den Umriss zeichnen., wofür die im Shape eingestellten Properties (Shape1.Pen) verwendet werden.
  • Alternativ könnte man auch zuerst das Rectangle zeichnen, dann das Rechteck um 1 pixel auf allen Seiten verkleinern und dann in dieses den Farbverlauf reinsetzen. Probier das doch mal als "Hausaufgabe".
Wow WP,

du solltest Lehrer werden. Wirklich du hast Talent Dinge zu erklären. Ganz toll. Ich habs echt kapiert. Danke.

kirchfritz
Beiträge: 219
Registriert: Mo 3. Jan 2011, 13:34
OS, Lazarus, FPC: Win11 (L 3.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Nürnberg

Re: TShape Farbverlauf

Beitrag von kirchfritz »

Ich habe Dir mal ein kleines Beispiel gemacht mit TBCPanel und einem BGRAShape
(siehe Anhang)
Screenshot 2025-05-17 061952.png
Screenshot 2025-05-17 061952.png (22.76 KiB) 631 mal betrachtet
Dateianhänge
GradientenTest.zip
(96.14 KiB) 149-mal heruntergeladen

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

Re: TShape Farbverlauf

Beitrag von Mathias »

Ich kannte dies auch nicht, und habe folgendes probiert.
Man kann auch ein ganzes Form damit befüllen.

Code: Alles auswählen

procedure TForm1.FormPaint(Sender: TObject);
begin
  Canvas.GradientFill(Rect(0, 0, ClientWidth, ClientHeight), clRed, clGreen, gdVertical);
end; 
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten