Stringgrid färbt sich um

Rund um die LCL und andere Komponenten
Antworten
Oldeman
Beiträge: 24
Registriert: Do 9. Jun 2022, 18:45

Stringgrid färbt sich um

Beitrag von Oldeman »

Hallo,
nach über 20 Jahren Delphi und nunmehr Lazarus arbeite ich mich zum ersten Mal in Stringgrid ein...
Das funzt prima, solange ich nicht in den Grid klicke: Dann färbt Lazarus den ganzen Grid auf weißen Hintergrund mit schwarzem Font um.
Warum? Was kann ich dagegen machen?
Dankbar für Tips
Oldeman

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

Re: Stringgrid färbt sich um

Beitrag von wp_xyz »

Stelle ein kleines Projekt zusammen, an dem man das Problem nachvollziehen kann. Packe die .pas, .lfm, .lpr und lpi-Dateien in ein gemeinsames zip, das kannst du dann unter "Dateianhänge" hier hochladen.

charlytango
Beiträge: 843
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Stringgrid färbt sich um

Beitrag von charlytango »

Alle nötigen Files eines Projektes zusammen suchen und zippen kann Lazarus übrigens selbst.

Menü -> Projekt -> Projekt publizieren.

Datenbankdateien extra dazu zippen

Linkat
Lazarusforum e. V.
Beiträge: 530
Registriert: So 10. Sep 2006, 23:24
OS, Lazarus, FPC: Linux Mint 21.3; Lazarus 3.0 FPC 3.2.2; RaspiOS
CPU-Target: AMD 64, ARM 32
Wohnort: nr Stuttgart

Re: Stringgrid färbt sich um

Beitrag von Linkat »

@charlytango
Danke, das "Projekt veröffentlichen" habe ich noch nicht gekannt.
Lesen bildet!!!!!
Linux Mint 21; Lazarus 2.2.4 FPC 3.2.2; RaspiOS

Oldeman
Beiträge: 24
Registriert: Do 9. Jun 2022, 18:45

Re: Stringgrid färbt sich um

Beitrag von Oldeman »

Hallo wp_xyz,

ich habe ziptestgrid.7z angehängt. Falls du damit nicht zurecht kommst, weil du Windows verwendest oder ein anderes Zip-Programm als P7Zip verwendest, dann lade ich die Dateien auf einen anderen Rechner und zippe sie dort.

Der Schalter swZ im Programm dient dazu, zu verhindern dass das Create-Event durchläuft, wenn das nicht gewünscht ist. Vielleicht ist hier das selbe Problem, wie das erwähnte.

@Charlytango / @Linkat: mit dem Zip-Programm von Lazarus bin ich nicht zurechtgekommen. Der Hilfe-Button bringt eine leere Maske und ich habe so nicht herausgefunden, wann das Programm was wohin zippt... Zu wenig zum Lesen -> zu wenig Bildung!!
ziptestgrid.7z
(2.23 KiB) 36-mal heruntergeladen

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: Stringgrid färbt sich um

Beitrag von af0815 »

Irgendwas verstehe ich an deinem Problem nicht. Bei mir macht es das, was du geschrieben hast. Ich habe deine Sourcen genommen, nur an meinen Debugger angepasst und unter Windows laufen lassen (Win10/64 alle Patches)
Screenshot 2023-01-26 125606.jpg
Screenshot 2023-01-26 125606.jpg (28.83 KiB) 943 mal betrachtet
Edit: Im Grid unter Option goRangeSelect abdrehen, wenn das bei dir auftritt. Hast du eine spezielle Tastatur oder Maus, die selbsttätig etwas selektieren kann. Ich kenne sowas im Bereich der Personen mit speziellen Bedürfnissen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Oldeman
Beiträge: 24
Registriert: Do 9. Jun 2022, 18:45

Re: Stringgrid färbt sich um

Beitrag von Oldeman »

Danke. Habe ich ausprobiert und Options->GoRangeSelect auf False gesetzt, war vorher True. Das Problem bleibt: sobald ich in den Grid klicke, werden alle bunten Zellen auf schwarz auf weiß umgefärbt.

Nein, weder habe ich besondere Bedürfnisse noch habe ich eine besondere Maus oder Tastatur. Beides ganz normal Cherry.

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

Re: Stringgrid färbt sich um

Beitrag von theo »

Dein Problem ist, dass du in TestGridDrawCell mit

Code: Alles auswählen

  if swZ then   
nur dann zeichnest, wenn gerade der Button gedrückt wurde, sonst springst du raus.
Du musst dort aber immer alles zeichnen können.
Dazu müsstest du dir die Zell-Farben anderweitig merken. Die Zelle kann das nicht.

Durch das Draufklicken oder Verändern der Grösse löst du ein Neuzeichnen aus.
Dann geht die ganze Farbinfo flöten.

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

Re: Stringgrid färbt sich um

Beitrag von wp_xyz »

Genau. Theo hat recht. Die Information, welche Zellen eingefärbt werden sollen, verschwindet nach dem ersten Neuzeichnen. Verschiebe mal das Grid nach links aus dem Bildschirm, so dass eine eingefärbte Zelle halb draußen ist, und schiebe das Grid dann wieder zurück - die Zelle bleibt halb eingefärbt, weil sie sich nicht mehr neu zeichnen kann.

Du musst also die Farb-Information unabhängig von deinem Click-Code speichern. Eine Möglichkeit wäre, die Eigenschaft Objects[Col, Row] des Grid zu verwenden. Denn das Grid speichert für jede Zelle nicht nur den Zell-String ab (Cells[Col, Row]), sondern kann auch jede beliebige Information in der Zelle speichern. Beliebige Information - das heißt, es wird als TObject gespeichert.

Um das auszunützen, kannst du dir eine Klasse TFarbe deklarieren, mit den beiden Elementen H und S für "Hintergrund" und 'Schrift", also wie deine Farbe_H und Farbe_S. In dem OnClick Ereignis erzeugst du eine neue Instanz dieser Klasse (farbe := TFarbe.Create), schreibst die beiden Farbwerte rein (z.B. farbe.H := clRed, farbe.S := clBlack) und hängst das dann in die Objects des Grid TestGrid.Objects[col, row] := farbe.

Code: Alles auswählen

type
  TFarbe = class
    S, H: TColor;
  end; 
  
procedure TFTestGrid.PbPasstClick(Sender: TObject);
Var
  ix, iy: Integer;
  Farbe: TFarbe;
begin
   Farbe := TFarbe.Create;

   If RbRot.Checked then Farbe.H:=clRed;
   If RbBlau.Checked then Farbe.H:=clBlue;
   If RbWeisz.Checked then Farbe.H:=clWhite;

   If RbSchwarz.Checked then Farbe.S:=clBlack;
   If RbGruen.Checked then Farbe.S:=clGreen;

   ix:=StrToInt(edX.Text);
   iy:=StrToInt(edY.Text);

   TestGrid.Cells[Iy, ix]:=edText.Text;
   TestGrid.Objects[IY, Ix] := Farbe;
end;  
Um das dann beim Zeichnen auszuwerten, kannst du weiterhin das OnDrawCell-Event verwenden, aber ich nehme lieber das OnPrepareCell-Event. Das kommt kurz vor dem Zeichnen und erlaubt, den Canvas des Grid nochmals anzupassen. Vorteil ist, dass du dich nicht mit der Text-Ausgabe, mit evtl. vorhandenen Checkboxen und Bildern herumschlagen musst.

In OnPrepareCell (bzw. halt in OnDrawCell) müssen wir abfragen, ob die aktuell zu zeichnende Zelle ein Object hat (if TestGrid.Objects[col, row] <> nil). Wenn ja, müssen wir das Objekt in ein TFarbe umdeklarieren (farbe := TFarbe(TestGrid.Objects[col, row]) und können dann die Farben für die Zelle auslesen und an den betreffenden Stellen im canvas des Grid eintragen:

Code: Alles auswählen

procedure TFTestGrid.TestGridPrepareCanvas(Sender: TObject; aCol,
  aRow: Integer; aState: TGridDrawState);
var
  farbe: TFarbe;
begin
   farbe := TFarbe(TestGrid.Objects[aCol, aRow]);
   if farbe <> nil then
   begin
     TestGrid.Canvas.Brush.Color := farbe.H;
     TestGrid.Canvas.Font.Color := farbe.S;
   end;
end;  
Eine Unschönheit gibt es noch: Jedes Objekt, das man selbst erzeugt hat, muss man selbst wieder zerstören, sonst hat man ein Speicherleck. Daher schreiben wir eine Methode ClearGrid, die alle Zellen durchläuft und nach Objects <> nil sucht und zerstört. Die Methode musst du aufrufen, wenn das Programm beendet wird, oder wenn sich die Anzahl der Spalten/Zeilen ändert:

Code: Alles auswählen

procedure TFTestGrid.ClearGrid;
var
  r, c: Integer;
begin
   for r := 0 to TestGrid.RowCount-1 do
     for c := 0 to TestGrid.ColCount-1 do
     begin
       TestGrid.Objects[c, r].Free;
       TestGrid.Objects[c, r] := nil;
     end;
end; 

procedure TFTestGrid.FormDestroy(Sender: TObject);
begin
   ClearGrid;
end; 
Dateianhänge
testgrid-wp.zip
(2.94 KiB) 35-mal heruntergeladen

Oldeman
Beiträge: 24
Registriert: Do 9. Jun 2022, 18:45

Re: Stringgrid färbt sich um

Beitrag von Oldeman »

Danke - da muss ich mich jetzt mal hineindenken. Klingt 1.) kompliziert und 2.) plausibel. Datagrid in .net ist einfacher. Wie gesagt: danke.

Antworten