2D Arrays - StringGrid

Für Fragen von Einsteigern und Programmieranfängern...
nevermore2k
Beiträge: 76
Registriert: Sa 1. Mai 2021, 15:39

2D Arrays - StringGrid

Beitrag von nevermore2k »

Ich möchte so ein kleines Griffbrett ( Akkord Diagram) programm schreiben. Hab erstmal grob in C was ausprobiert.

das ist der output in C

Bild

Code: Alles auswählen

#include <stdio.h>

int main() {
  char griffbrett[6][4];

  int x,y;

  for (x=0; x<6; x++)
    for (y=0; y<4; y++)
      griffbrett[x][y]='|';

  griffbrett[0][0] = '0';
  griffbrett[1][1] = 'x';
  griffbrett[2][0] = '0';
  griffbrett[3][2] = 'x'; 
  griffbrett[4][3] = 'X';   
  griffbrett[5][0] = '-';
  
  for (x = 0; x < 6; x++)
  {
    for (y = 0; y < 4; y++)
    {
      printf("--%c--", griffbrett[x][y]);
    }
    putchar('\n');
  }
  return 0;
}
Jetzt dachte ich mir, ich setze das mal in Lazarus um.


Bild
Das kommt dabei heraus...

ich verstehe nicht sooo ganz warum die erste reihe nicht genau so reagiert wie in c... hab vermutlich einen denkfehler drinnen. und komme nicht darauf.

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

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

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    StringGrid1: TStringGrid;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
type
  griffbrett = array [0..6, 0..4] of char;
var
  gbrett: griffbrett;
  x, y: integer;
begin

  for x := 0 to 6 do
    for y := 0 to 4 do
      gbrett[x, y] := ' ';

  gbrett[0, 0] := '0';
  gbrett[1, 1] := 'X';
  gbrett[2, 0] := '0';
  gbrett[3, 2] := 'X';
  gbrett[4, 3] := 'X';
  gbrett[5, 0] := '-';



  for x := 0 to 6 do
    for y := 0 to 4 do
      StringGrid1.Cells[x, y] := gbrett[x, y];

end;

procedure TForm1.FormCreate(Sender: TObject);
var
  s: TTextStyle;
begin
  s := StringGrid1.DefaultTextStyle;
  s.Alignment := taCenter;
  StringGrid1.DefaultTextStyle := s;
end;

end.

Benutzeravatar
Winni
Beiträge: 796
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.0.12, fpc 3.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: 2D Arrays - StringGrid

Beitrag von Winni »

Hi!

Ganz einfach: weil Du x und y verwechselst .....

Dann klappts auch mit C-Dur

Keep on rockin

Winni

nevermore2k
Beiträge: 76
Registriert: Sa 1. Mai 2021, 15:39

Re: 2D Arrays - StringGrid

Beitrag von nevermore2k »

oh ok, naja immerhin nur das :)
gleich mal schauen obs klappt wenn ich die ändere.

Danke !

nevermore2k
Beiträge: 76
Registriert: Sa 1. Mai 2021, 15:39

Re: 2D Arrays - StringGrid

Beitrag von nevermore2k »

So gehts

Code: Alles auswählen

 StringGrid1.Cells[y, x] := gbrett[x, y];  
ja, da war ich etwas blind :) danke !

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

Re: 2D Arrays - StringGrid

Beitrag von wp_xyz »

Also diese Tabulatur würde mich verwirren, denn ich assoziiere die Gitterlinien mit den Saiten, und in deinem Layout müsse ich dann zwischen die Saiten greifen...

Timm Thaler
Beiträge: 1206
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: 2D Arrays - StringGrid

Beitrag von Timm Thaler »

wp_xyz hat geschrieben:
Fr 21. Mai 2021, 00:14
Also diese Tabulatur würde mich verwirren, denn ich assoziiere die Gitterlinien mit den Saiten, und in deinem Layout müsse ich dann zwischen die Saiten greifen...
Jo, ich würd das auch auf ein Image malen.

nevermore2k
Beiträge: 76
Registriert: Sa 1. Mai 2021, 15:39

Re: 2D Arrays - StringGrid

Beitrag von nevermore2k »

Ja, Ideal ist diese Darstellung wirklich nicht :)

Ich suche noch nach der besten Möglichkeit wie man sowas umsetzen kann. Am besten so das man auch auf die Bünde klicken kann, und dann auch einen Wert wieder zurückbekommt welcher Bund auf welcher Saite gedrückt wurde usw.

Benutzeravatar
six1
Beiträge: 403
Registriert: Do 1. Jul 2010, 19:01

Re: 2D Arrays - StringGrid

Beitrag von six1 »

An den C Output kommst du ran, wenn du ein Memo nimmst und als Schrift z.B. Consolas.
Gruß, Michael

Benutzeravatar
Winni
Beiträge: 796
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.0.12, fpc 3.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: 2D Arrays - StringGrid

Beitrag von Winni »

99Hi!

Dann machen wir mit dem StringGrid weiter, müssen uns aber die einzelnen Zellen selber pinseln.

Beim StringGrid;
* Die GridLineWidth auf Null setzen
* DefaultDrawing auf false setzten

Bei den Ereignissen bei onDrawCell folgende Procedure einklinken:

Code: Alles auswählen

procedure TForm1.StringGrid1DrawCell(Sender: TObject; aCol, aRow: Integer;
	 aRect: TRect; aState: TGridDrawState);
   var x,y : Integer;
    s : string;
begin
  y := (aRect.Bottom - aRect.Top ) div 2 + aRect.Top;
  StringGrid1.Canvas.Brush.Color := clWhite;
  StringGrid1.Canvas.FillRect(aRect);
  StringGrid1.Canvas.Pen.Color := clRed;
  StringGrid1.Canvas.Line(aRect.left,y,Arect.Right,y);
  s := StringGrid1.Cells[aCol,aRow];
  x := (aRect.Right -aRect.left -
          StringGrid1.Canvas.TextWidth(s) ) div 2 +
          aRect.Left;
  StringGrid1.Canvas.TextOut(x,aRect.Top+2,s);
end;

Nun hast Du rote Saiten mit schwarzer Beschriftung auf weißem Untergrund.

Das ist mit Lazarus 2.0.12 gemacht. Bei älteren Versionen musste man auch noch mit dem DrawStyle (oder so?) rummachen. Hab ich aber nicht mehr im Kopf.

Winni

Benutzeravatar
Winni
Beiträge: 796
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.0.12, fpc 3.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: 2D Arrays - StringGrid

Beitrag von Winni »

Hi!

Ich hab die Bünde vergessen!
Also onDrawCell noch mal:

Code: Alles auswählen

procedure TForm1.StringGrid1DrawCell(Sender: TObject; aCol, aRow: Integer;
	 aRect: TRect; aState: TGridDrawState);
   var x,y, CenterX : Integer;
    s : string;
begin
  y := (aRect.Bottom - aRect.Top ) div 2 + aRect.Top;
  StringGrid1.Canvas.Brush.Color := clWhite;
  StringGrid1.Canvas.FillRect(aRect);
  StringGrid1.Canvas.Pen.Color := clRed;
  StringGrid1.Canvas.Line(aRect.left,y,Arect.Right,y);
  CenterX := (aRect.Right -aRect.left) Div 2 + aRect.Left;
  StringGrid1.Canvas.Pen.Color := clBlue;
  StringGrid1.Canvas.Line(CenterX,aRect.Top, CenterX,ARect.Bottom);

  s := StringGrid1.Cells[aCol,aRow];
  x :=  CenterX - StringGrid1.Canvas.TextWidth(s)  div 2;
  StringGrid1.Canvas.TextOut(x,aRect.Top+2,s);
end;               
Sorry.
Winni

nevermore2k
Beiträge: 76
Registriert: Sa 1. Mai 2021, 15:39

Re: 2D Arrays - StringGrid

Beitrag von nevermore2k »

Ihr seid super :)

nevermore2k
Beiträge: 76
Registriert: Sa 1. Mai 2021, 15:39

Re: 2D Arrays - StringGrid

Beitrag von nevermore2k »

Bild

Das wäre in jedem Fall schonmal eine Möglichkeit. Mehr Zentrieren kann ich die Buchstaben nicht, da die ansonsten verschwinden.

Benutzeravatar
Winni
Beiträge: 796
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.0.12, fpc 3.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: 2D Arrays - StringGrid

Beitrag von Winni »

Hi!

Damit auch der Rest sehen kann, wie C-Dur im StringGrid aussieht: Anhang

Winni
Dateianhänge
StringGrid_C-Dur.png
StringGrid_C-Dur.png (4.19 KiB) 180 mal betrachtet

nevermore2k
Beiträge: 76
Registriert: Sa 1. Mai 2021, 15:39

Re: 2D Arrays - StringGrid

Beitrag von nevermore2k »

Noch eine kleine Änderung gemacht, das man sieht, dass die Leersaiten nicht gegriffen werden müssen :)
Bild

eine kurze Frage zu" if then else" .

Code: Alles auswählen

 if (acol = 0) then
     StringGrid1.Canvas.TextOut(x, aRect.Top - 2, s)
    else
  StringGrid1.Canvas.TextOut(x - 28, aRect.Top - 2, s);    
  
Das hat mich gerade 15 Minuten gekostet, und zwar nur deshalb bis ich aus Frust das Semikolon vor dem else in der Zeile davor gelöscht habe... wieso darf da keines hin ?

Benutzeravatar
Winni
Beiträge: 796
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.0.12, fpc 3.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: 2D Arrays - StringGrid

Beitrag von Winni »

nevermore2k hat geschrieben:
Fr 21. Mai 2021, 14:06
Bild

Das wäre in jedem Fall schonmal eine Möglichkeit. Mehr Zentrieren kann ich die Buchstaben nicht, da die ansonsten verschwinden.
Hi!

1. sollst Du nicht mehr zentrieren, sondern der Finger soll möglichst nah hinter dem Bund greifen.

2. Wenn Du nicht weisst, warum da was beim "mehr Zentrieren" verschwindet, dann schau Dir mal den Source an. Wenn das nicht hilft; GridLineWidth mal probehalber auf 1 stellen.

Winni

Antworten