Scambio tra di loro pannelli colorati

di il
17 risposte

Scambio tra di loro pannelli colorati

Salve a tutti.Ho sette panelli colorati :giallo,blu, ecc,in orizzontale nella form distanti tra loro di alcuni spazi. Vorrei scambiare il colore tra di loro. Sto usando il comando per generare rnumeri casuali ma non riesco ad abbinarli allo swap.Se delphi prevedesse array di componenti verrebbe tutto più facile. Molti anni fa usai una delle prime versioni di visual basic ed aveva anchè array di componenti.Qualcuno sa se (Calembur ) delphi prevede questo tipo di array?La versione che uso è la 10.3

17 Risposte

  • Re: Scambio tra di loro pannelli colorati

    Per eseguire la scansione dei componeti su una form la VCL di delphi prevede la property "Controls" sul componente "padre" dunque se i tuoi TPanel li hai messi direttamente nella form ti basta fare un semplice ciclo for su tutti i Controls e quando incontri un TPanel ci fai quello che vuoi, la versione semplice potrebbe essere qualcosa del tipo:
    
    var x: integer;
    begin
      // In questo caso i tpanel sono sulla form dunque tutto liscio
      for x := 0 to ControlCount - 1 do
        if (Controls[x] is TPanel) then
          (Controls[x] as TPanel).color := miocolore;
    end;
    
    Dato che usi la versione 10.3, potresti a usare qualcosa di più attuale, ossia RTTI con anonimi, adesso non ho delphi sotto mano ma appena riesco vedo di postare un esempio
    W.
  • Re: Scambio tra di loro pannelli colorati

    Una precisazione, ho sbagliato,in realtà uso la versione 7 della borland.detto questo, se ho capito il tuo codice, non c'è uno swap tra i panel colorati, in caso contrario scusami se non l'ho capito. i 7 panelli sono già colorati,voglio solo cambiare i colori, es.se il 1°è bianco il 2° è verde e così via con gli altri cinque di diversi colori, la mia intenzione è quella di creare una nuova sequenza tanto da avere i panel colorati sempre diversi.I 7 pannelli sono messi tutti in fila orizzontalmente. Comunque grazie della risposta.
  • Re: Scambio tra di loro pannelli colorati

    Non credo che esiste una funzione di swap insita nella VCL fatta "ad HOC" per te,ma per crearla ci vuole molto poco, cmq se a te serve avere sempre i 7 pannelli di colore diverso un idea "al volo":
    Ai 7 Tpanel che hai creato assegni nella property TAG il valore progressivo da 0 a 6, crei un array da 0 a 6 di tipo TColor (aColor: Array[0..6] of TColor), modifichi questo array a tuo piacimento con i colori che desideri, poi con un ciclo secco gli setti il valore in base al tag andando a pescarlo dall'array, qualcosa del tipo:
    
    // dichiarazione nella sezione private della classe form
    aColor: Array[0..6] of TColor
    ....
    // assegnazione dei colori random
      for x := 0 to 6 do
        aColor[x] := GenerateRandomColor;
    ...
    // assegnazione dei colori ai vari pannelli
    for x := 0 to ControlCount - 1 do
        if (Controls[x] is TPanel) then
          (Controls[x] as TPanel).color := aColor[(Controls[x] as TPanel).tag];
    
    Sperando di aver capito la situazione.

    PS: Codice non testato scritto al volo senza compilatore
  • Re: Scambio tra di loro pannelli colorati

    A dir la verità avevo pensato ad un array col tag dei singoli pannelli ma non sapevo come collegarli, la tua idea mi pare buona, adesso mi è venuto in mente una cosa, se non va provo il tuo consiglio. Grazie
  • Re: Scambio tra di loro pannelli colorati

    Ho usato la seguente modalità:
    private
    { Private declarations }
    aColor: Array[1..8] of TColor ; //dichiarazione array di colori
    public
    { Public declarations }
    end;

    //assegazione colori nell'array
    procedure TForm1.FormCreate(Sender: TObject);
    begin
    Acolor[1]:=clBlacK;
    Acolor[2]:=clred;
    Acolor[3]:=clyellow;
    Acolor[4]:=clwhite;
    Acolor[5]:=clGrayText;
    Acolor[6]:=clMaroon;
    Acolor[7]:=clBlue;
    end;
    VAR
    cl:array [1..7] of word;
    // azzeramento 7 elementi array
    for i := 1 to 7 do
    cl:=0;

    //7 numeri random con controllo senza doppioni nell'array cl[?]
    for i:= 1 to 7 do begin
    Randomize;
    repeat
    b:=true;
    d:=random((7)*1)+1;
    for c:= 1 to 7 do
    if cl[c]= d then
    b:=false;
    until (b= true);
    cl:= d;
    end;

    //assegnazioni colori ai pannelli nella Form con nome p1-p2 ecc
    for i :=1 to 7 do begin
    case i of
    1:p1.Color:=Acolor[cl];
    2:p2.Color:=Acolor[cl];
    3:p3.Color:=Acolor[cl];
    4:p4.Color:=Acolor[cl];
    5:p5.Color:=Acolor[cl];
    6:p6.Color:=Acolor[cl];
    7:p7.Color:=Acolor[cl];

    end;
    end;
    Funziona però mi manca ancora l'assegnazione caption con relativo nome del colore dei panelli che però c'è uno scambio di posizione.Ho fatto alcune prove ma non funziona.I pannelli hanno tag progressiivi -p1 tag1, p2. tag2 ecc
  • Re: Scambio tra di loro pannelli colorati

    A vedere il codice "credo" sia meglio usare una funzione di shuffle, ossia "mischiamo le carte in tavola", per tenere le caption legate ai colori la modalità più semplice che mi viene in mente è quella di creare un array di caption parallelo a quello dei colori e tenerli insieme con un terzo array che lavora come indice, in questo modo si hanno 2 array statici, colori e label, ed uno dinamico che lavora, con D7 non credo che puoi usare tutte le nuove feature che sono state implementate nel tempo, dunque per questo esempio ho ragionato solo sull'uso di array:
    Nella form sono presenti 7 componenti TPanel e 7 componenti TCaption con il tag assegnato da 1 a 7, ho usato delle label perchè nel caso di nero su nero la caption del tpanel andrebbe oscurara (o lavorata), ma cambia poco, le proprietà dei pannelli ParentColor e ParentBackground devono essere settate a false.
    
    //nella sezione private della classe form definisco un array di lavoro di interi
    private 
        aDummyIndex: Array[1..7] of Integer;
        
    // Definisco delle costanti per il numero di volte che voglio mischiare le carte e per il numero dei colori
    const
     SHUFFTIME = 60;
     NUMCOLOR = 7;
     // definisco i 2 array di colori e di label come array statici preinizializzati
     aColor: Array[1..7] of TColor = (clBlacK, clRed, clyellow, clWhite,
                                      clGrayText, clMaroon, clBlue);
     aCaption: Array[1..7] of String = ('Nero', 'Rosso', 'Giallo', 'Bianco',
                                      'Grigio', 'Marrone', 'Blu');   
     
    // in fase di creazione setto l'array di lavoro e faccio il display di base
    procedure TForm1.FormCreate(Sender: TObject);
    var  x: Integer;
    begin
      for x := Low(aDummyIndex) to High(aDummyIndex) do
        aDummyIndex[x] := i;
      ScriviResult;
    end;
                                      
    // il metodo (Procedura) ScriviResult mi serve per riassegnare colore e caption       
    Procedure TForm1.ScriviResult;
    var
      x: Integer;
    begin
    // per tutti i controlli della form
      for x := 0 to ControlCount - 1 do
      begin
        if (Controls[x] is TPanel) then
        begin
          (Controls[x] as TPanel).color := aColor[aDummyIndex[(Controls[x] as TPanel).tag]];
          (Controls[x] as TPanel).caption := aCaption[aDummyIndex[(Controls[x] as TPanel).tag]];
        end
        else if (Controls[x] is TLabel) then
          (Controls[x] as TLabel).Caption := aCaption[aDummyIndex[(Controls[x] as TLabel).tag]];
      end;
    
    end;    
    
    // mischio le carte in tavola
    procedure TForm1.shuffle;
    var
      Index, x: Integer;
      index1, index2: Integer;
    begin
      Randomize;
      for x := 0 to SHUFFTIME do
      begin
        index1 := Random(NUMCOLOR) + 1;
        index2 := Random(NUMCOLOR) + 1;
        Index := aDummyIndex[index1];
        aDummyIndex[index1] := aDummyIndex[index2];
        aDummyIndex[index2] := Index;
      end;
    end;  
    
    // quando premo il bottone
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      shuffle;
      ScriviResult;
    end;  
                      
    




    Un saluto
    W.
  • Re: Scambio tra di loro pannelli colorati

    Forse ti avevo letto nel pensiero perchè una cosa simile l'avevo atttuata ed ho aggiunto un array, e come vedi i nomi dei colori ci sono,solo che le caption non compaiono sempre specialmente col bianco e il giallo, e non capisco perchè, un comando o funziona o non funziona, specialemente se ricorsivo,boh.Queste sono le aggiunte ed l'output attuale, ma con un ma..
    private
    { Private declarations }
    // ho aggiunto questo array
    stri: Array[1..8] of string;
    aColor: Array[1..8] of TColor ;

    procedure TForm1.FormCreate(Sender: TObject);
    begin

    Acolor[1]:=clBlacK;
    Acolor[2]:=clred;
    Acolor[3]:=clyellow;
    Acolor[4]:=clwhite;
    Acolor[5]:=clGrayText;
    Acolor[6]:=clMaroon;
    Acolor[7]:=clBlue;

    //aggiunta successivamente

    stri[1]:='Nero';
    stri[2]:='Rosso';
    stri[3]:='Giallo';
    stri[4]:='Bianco';
    stri[5]:='Verde';
    stri[6]:='Marron';
    stri[7]:='Blu';
    end;


    for i :=1 to 7 do begin
    case i of
    1:begin
    p1.Color:=Acolor[cl];
    // poi ho aggiunto questo nuovo comando su tutti
    p1.caption:=stri[cl];
    end;
    2:begin
    p2.Color:=Acolor[cl];
    p2.caption:=stri[cl];
    end;
    3:begin
    p3.Color:=Acolor[cl];
    p3.caption:=stri[cl];
    end;
    4:begin
    p4.Color:=Acolor[cl];
    p4.caption:=stri[cl];
    end;
    5:begin
    p5.Color:=Acolor[cl];
    p5.caption:=stri[cl];
    end;
    6:begin
    p6.Color:=Acolor[cl[i]];
    p6.caption:=stri[cl[i]];
    end;
    7:begin
    p7.Color:=Acolor[cl[i]];
    p7.caption:=stri[cl[i]];
    end;
    end;
    end;

  • Re: Scambio tra di loro pannelli colorati

    A prima vista darei la colpa al colore bianco del font, se il bianco o il giallo cadono nei primi 4 pannelli, bianco su bianco/giallo, non si distingue.
  • Re: Scambio tra di loro pannelli colorati

    // tuo codice
    procedure TForm1.FormCreate(Sender: TObject);
    var x: Integer;
    begin
    for x := Low(aDummyIndex) to High(aDummyIndex) do
    aDummyIndex[x] := i; // questa i cos'è?
  • Re: Scambio tra di loro pannelli colorati

    Sicuramente un errore di copia incolla ....
    for x := Low(aDummyIndex) to High(aDummyIndex) do
    aDummyIndex[x]:=x;

    inizializzo array con i numeri da 1 a 7
  • Re: Scambio tra di loro pannelli colorati

    Ho provato il tuo codice ma dà lo stesso problema che dà il mio.A volte sul pannello bianco e giallo non compare la caption,a volte compaiono su tutti e due, oppure a volte la caption compare sul giallo e sul bianco no,e viceversa.A volte, ma meno che col bianco e giallo, non compaiono le caption degli altri pannelli, a volte le caption compaiono su tutti.Sulle label invece compaiono in modo regolare.Magari sarà perchè sui pannelli in alcuni casi (che non ho capito quali) le caption prendono i colori dei pannelli stessi? Se fosse così non riesco a capire in quale modo posso risolvere.Non è che abbia molta importanza, lo voglio ottenere solo per aggiungere conoscenza nell'uso di delphi, e questo mi pare un problema interessante da risolvere.

    ps. scusa tanto il ritardo, mi pare giusto farti gli auguri di buon anno
  • Re: Scambio tra di loro pannelli colorati

    Prova questo codice per assegnare il colore alla caption del panel
    https://www.askingbox.com/tip/delphi-lazarus-readable-font-color-for-arbitrary-background-color

    Buon Anno anche a te e a tutto il forum

    W.
  • Re: Scambio tra di loro pannelli colorati

    Ok, proverò anche questo, però ti voglio mettere al corrente di una cosa cui non trovo attinenza. Il tuo codice l'avevo implementato nello stesso mio progetto (commentandolo tutto) della stessa cartella, successivamente (ed è per questo che non capisco l'attinenza) ho creato una nuova cartella ed un nuovo progetto col tuo codice, il tutto salvato nella nuova cartella, e.....funziona, nel giallo e nel bianco le caption ci sono,e quindi sono basito, che attinenza c'è? Boh.Rimane un piccolo problema dei pannelli scuri coè il nero, blu ecc,in cui le caption non si vedono, ma forse sarà, come dicevo nella precedente,il fatto che la caption sia colorata come il pannello scuro, rimane il resto, perchè non è tanto importante che tutto funzioni (sarebbe importante se il programma fosse commissionato, ma dato che non lo è in questo caso voglio solo capire). Vedrò se questo tuo ulimo consiglio sulle caption funziona.Comunque tu sei bravo col delphi. Saluti
  • Re: Scambio tra di loro pannelli colorati

    Ho provato anche io ad implementare la funzione che ho trovato, e devo dire che funziona benone, ti posto il .pas che ho buttato giù in 5 min 7 pannelli, 7 label e 1 bottone, i tag sia dei pannelli che delle label vanno da 1 a 7
    
    unit Unit21;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
    
    type
      TForm21 = class(TForm)
        Panel1: TPanel;
        Panel2: TPanel;
        Panel3: TPanel;
        Panel4: TPanel;
        Panel5: TPanel;
        Panel6: TPanel;
        Panel7: TPanel;
        Button3: TButton;
        Label1: TLabel;
        Label2: TLabel;
        Label3: TLabel;
        Label4: TLabel;
        Label5: TLabel;
        Label6: TLabel;
        Label7: TLabel;
        procedure FormCreate(Sender: TObject);
        procedure Button3Click(Sender: TObject);
      private
        aDummyIndex: Array[1..7] of Integer;
        procedure scrivi;
        procedure shuffle;
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form21: TForm21;
    const
     SHUFFTIME = 50;
     NUMCOLOR = 7;
     aColor: Array[1..NUMCOLOR] of TColor = (clBlacK, clRed, clyellow, clWhite,
                                      clGrayText, clMaroon, clBlue);
     aCaption: Array[1..NUMCOLOR] of String = ('Nero', 'Rosso', 'Giallo', 'Bianco',
                                      'Grigio', 'Marrone', 'Blu');
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm21.shuffle;
    var
      Index, x: Integer;
      index1, index2: Integer;
    begin
      Randomize;
      for x := 0 to SHUFFTIME do
      begin
        index1 := Random(NUMCOLOR) + 1;
        index2 := Random(NUMCOLOR) + 1;
        Index := aDummyIndex[index1];
        aDummyIndex[index1] := aDummyIndex[index2];
        aDummyIndex[index2] := Index;
      end;
    end;
    
    procedure TForm21.Button3Click(Sender: TObject);
    begin
      shuffle;
      Scrivi;
    end;
    
    function GetContrastColorBlackOrWhite(const AColor: TColor): TColor;
    var
      R, G, B: single;
    begin
      R := GetRValue(AColor) * 0.25;
      G := GetGValue(AColor) * 0.625;
      B := GetBValue(AColor) * 0.125;
    
      if (R + G + B) > 128 then
        result := clBlack
      else
        result := clWhite;
    end;
    
    Procedure TForm21.scrivi;
    var
      x: Integer;
    begin
      for x := 0 to ControlCount - 1 do
      begin
        if (Controls[x] is TPanel) then
        begin
          (Controls[x] as TPanel).color := aColor[aDummyIndex[(Controls[x] as TPanel).tag]];
          (Controls[x] as TPanel).caption := aCaption[aDummyIndex[(Controls[x] as TPanel).tag]];
          (Controls[x] as TPanel).Font.Color := GetContrastColorBlackOrWhite(aColor[aDummyIndex[(Controls[x] as TPanel).tag]]);
        end
        else if (Controls[x] is TLabel) then
          (Controls[x] as TLabel).Caption := aCaption[aDummyIndex[(Controls[x] as TLabel).tag]];
      end;
    
    end;
    
    procedure TForm21.FormCreate(Sender: TObject);
    var I: Integer;
    begin
      for i := Low(aDummyIndex) to High(aDummyIndex) do
        aDummyIndex[i]:=i;
     scrivi;
    end;
    
    end.
    
Devi accedere o registrarti per scrivere nel forum
17 risposte