Italian community of Lazarus and Free Pascal

Programmazione => Componenti Aggiuntivi => Topic aperto da: Avogadro - Dicembre 21, 2021, 10:55:25 pm

Titolo: rxdbgrid
Inserito da: Avogadro - Dicembre 21, 2021, 10:55:25 pm
Ho installato la mitica libreria RxLib

https://wiki.lazarus.freepascal.org/RXfpc

Il componente che uso per la maggiore è la RxDbGrid, che permette di fare cose carine, tipo le righe multilinee, la possibilità di avere l' hint sui titoli delle colonne etc .

RxDbgrid ha sempre funzionato egregiamente , fin dai tempi del buon vecchio delphi 5

Ora stavo aggiornando un sw per delle carte di controllo e una rxdbgrid (ne uso 3, relazioni master-detail in cascata) , la prima,  ad un certo punto non mostra piu' il testo, le celle restano a run time bianche - il testo compare a design time -, vedasi allegato .

L' ho disinstallata e reinstallata, ma niente il bug si ripresenta sempre sulla stessa ztable (uso zeos e slqlie)

Qualcuno ha un' idea di cosa possa mai succedere che scompare il testo della rxdbgrid a runtime?

Ho cercato sul web ma non ho trovato segnalazioni di casi simili.

Dovro' tornare alla buona vecchia dbgrid di lazarus,  ma come si fa allagare le righe in maniera dinamica in funzione della lunghezza del testo ?  Le dbgrid con le righe tutte larghe sono visivamente orribili

Alternativamente: c'è un'altra  dbgrid performante in un qualche pkg ?

Titolo: Re:rxdbgrid
Inserito da: DragoRosso - Dicembre 22, 2021, 12:02:10 am
Non conosco quei componenti.

Ma dalle immagini, noto che la prima riga della prima tabella in design mostra nel primo campo data e ora. La seconda riga invece no.

Non è che hai qualche definizione incongruente nella griglia / database ? O il contenuto del DB non collima (si, sò che stò probabilmente dicendo una ca..ata, ma nel passato mi è capitato proprio con data e ora) ?

Ciao
Titolo: Re:rxdbgrid
Inserito da: bonmario - Dicembre 22, 2021, 08:11:02 am
Ciao,
non conosco quel componente, in passato mi è successo che se nel testo c'erano lettere accentate o caratteri particolari, nascondesse il tutto.
Prova a vedere se ti fa lo stesso scherzo con dati che contengono solo lettere e numeri.

Per quanto riguarda le celle su più righe, io uso questa da anni, sia in Windows che in Linux:

Codice: [Seleziona]
{Permette di scrivere una cella su più righe tramite l'utilizzo del LineEnding.
Aggiungere il richiamo della presente "procedure" all'interno della "DrawCell"}
procedure ScriviCellaSuPiuRighe(Sender:TObject; aCol, aRow:Integer; aRect:TRect; VFSistemaColori:Boolean = True; Allineamento:TAlignment = taLeftJustify);
var WrkStr:String;
    DrawRect:TRect;
    WrkAltRiga:Longint;

  function PreparaFlags(Flags: Cardinal): Cardinal;
  begin
    case Allineamento of
      taLeftJustify : Result:=Flags or DT_LEFT  ;
      taRightJustify: Result:=Flags or DT_RIGHT ;
      taCenter      : Result:=Flags or DT_CENTER;
    else
      Result:=Flags;
    end;
  end;

begin
  with (Sender as tStringGrid), Canvas do begin
    { erase earlier contents from default drawing }
    if VFSistemaColori then begin
      if (aRow >= FixedRows) and (aCol >= FixedCols) then begin
        //Se la riga è selezionata, e tra le opzioni della tabella
        //c'è la selezione per riga, cambio il colore dello sfondo
        if (aRow = Row) and (goRowSelect in Options) then begin
          Brush.Color:=SelectedColor;
          Font.Color:=clWhite;
        end else begin
          Brush.Color:=Color;
          Font.Color:=clWindowText;
        end;
      end else begin
        Brush.Color:=FixedColor;
        Font.Color:=clWindowText;
      end;
    end;
    FillRect(aRect);

    { get cell contents }
    WrkStr:=Cells[aCol, aRow];
    if Length(WrkStr) > 0 then begin
      { copy of cell rectangle for text sizing }
      DrawRect:=aRect;

      if (Pos(LineEnding, WrkStr) > 0) then begin
        //Se la riga da emettere contiene "LineEnding", riformatto la cella
        {$IFDEF LINUX}
          //Dopo aver aggiornato Ubuntu alla 20.04, se la cella era su più righe, l'ultima riga veniva
          //tagliata.
          //Questo è l'unico modo "empirico" con cui sono riuscito a risolvere
          WrkStr:=WrkStr + LineEnding + LineEnding + LineEnding + LineEnding;
        {$ENDIF}

        { get size of text rectangle in DrawRect, with word wrap }
        DrawText(Handle, PChar(WrkStr), Length(WrkStr), DrawRect, PreparaFlags(DT_CALCRECT or DT_WORDBREAK));
        WrkAltRiga:=DrawRect.Bottom - DrawRect.Top;
        if (WrkAltRiga > RowHeights[aRow]) then begin
          //L'altezza della cella deve essere variata perché la cella ridisegnata è più alta o più bassa
          //N.B. La cella potrebbe essere più bassa quando, ad esempio diminuisco l'altezza del
          //     font a runtime, passando ad esempio da 20 a 12
          { cell word-wraps; increase row height }
          RowHeights[aRow]:=WrkAltRiga;
          {$IFDEF LINUX}
            //Su Linux, senza l'istruzione qui sotto, la cosa funzionerebbe solo
            //dopo aver cliccato su una cella qualsiasi della riga
            (Sender as TStringGrid).Repaint;
          {$ENDIF}
        end else begin
          { cell doesn't word-wrap }
          DrawRect.Right:=aRect.Right;
          FillRect(DrawRect);
          DrawText(Handle, PChar(WrkStr), Length(WrkStr), DrawRect, PreparaFlags(DT_WORDBREAK));
        end;
      end else begin
        //La cella da emettere non contiene "LineEnding": scrivo direttamente
        DrawText(Handle, PChar(WrkStr), Length(WrkStr), DrawRect, PreparaFlags(DT_SINGLELINE or DT_VCENTER));
      end;
    end;
  end;
end;

La devi richiamare nella "OnDrawCell", qui un esempio:
Codice: [Seleziona]
procedure TForm1.TabellaNoteDrawCell(Sender: TObject; aCol, aRow: Integer;
  aRect: TRect; aState: TGridDrawState);
begin
  ScriviCellaSuPiuRighe(Sender, aCol, aRow, aRect, False);
end;

La parte del codice che riguarda l'allineamento, magari non ti interessa, toglila pure.
Probabilmente ti servirà qualche definizione per farla funzionare, se c'è qualcosa che non ti quadra, chiedi pure, ma di sicuro non ti risponderò mai a mezzanotte !!! (mentre rispondevo ho notato l'ora in cui hai postato !!!)

Ciao, Mario
Titolo: Re:rxdbgrid
Inserito da: Avogadro - Dicembre 22, 2021, 09:56:57 am
Grazie per i suggerimenti.

Fortuna che avevo una copia di backup su una chiavetta usb , solo che adesso non so che fare : proseguo con la rxdbgrid o torno alla dbgrid con i suggerimenti di cui sopra ?

Anche secondo me c'è una qualche inconguenza da qualche parte, il problema è trovarla , si c'è il debug, ma il problema è trovare il tempo per scorrere il codice.

Come diceva il buon Mario il tempo vola e in un attimo si fanno le 11 di sera e a quell' ora stare li a leggere il codice sorgente  ...

Aggiungo altre informazioni, magari il problema è qui, proprio nelle informazioni .

Mi spiego meglio:

per le carte di controllo ci sono una serie di variabili che hanno un loro ruolo: la media, il range, la tolleranza, le misure etc;

quel che stavo cercando di fare era spiegare nell' hint dei titoli della rxbgrid cosa erano le variabili e quali erano i valori che dovevano avere (alias quale era il loro dominio) ;

il problema della scomparsa delle scritte (valori numerici compresi) si è presentato dopo che ho fatto gli hint della maggior parte dei titoli delle colonne della dbgrid; è come se il "sistema rxdbgrid" non reggesse piu' di tante informazioni; succedeva qualcosa di simile con le prime versioni di delphi su windows: se si metteva qualche icona in piu' o qualche hint in piu' l' eseguibile andava in crash  per mancanza di "hand" ;

si , c'è da qualche parte l' help contestuale,  devo provarlo ad implentarlo, solo che no trovato granché in merito sul web

ciao a tutti e grazie ancora e soprattutto buone feste


 









Titolo: Re:rxdbgrid
Inserito da: DragoRosso - Dicembre 22, 2021, 10:13:08 am
Purtroppo è il lavoro del programmatore.
Scrivere codice nuovo per gestire la DBGrid classica è comunque un impegno, magari relativo se l'hai già fatto, ma comunque un impegno. Tra l'altro non ti mantiene al riparo da futuri aggiornamenti della DBGrid stessa che rendano incompatibile il tuo codice.

Cercare di capire cosa c'è che non và forse è la strada preferibile e meno impegnativa, almeno secondo il mio punto di vista.

Apporfitto per linkare una canzonicina ........ sentitela che è divertente, si addice alla situazione e rispecchia un pò tutti noi.

http://www.donadeo.net/wp-content/uploads/2008/01/ballata_del_programmatore.mp3 (http://www.donadeo.net/wp-content/uploads/2008/01/ballata_del_programmatore.mp3)

Il testo di questa opera è di Enrico Colombini, arrangiamenti di Marco Di Francesco, voce Domenico Agostino, musica da "Il pescatore" di Fabrizio De Andrè.

Ciao
Titolo: Re:rxdbgrid
Inserito da: DragoRosso - Dicembre 22, 2021, 10:26:32 am
il problema della scomparsa delle scritte (valori numerici compresi) si è presentato dopo che ho fatto gli hint della maggior parte dei titoli delle colonne della dbgrid; è come se il "sistema rxdbgrid" non reggesse piu' di tante informazioni; succedeva qualcosa di simile con le prime versioni di delphi su windows: se si metteva qualche icona in piu' o qualche hint in piu' l' eseguibile andava in crash  per mancanza di "hand" ;

Per gli Hint, quello che ti consiglio è gestire l'HINT dinamico, ossia quando il mouse si muove su un zona del componente (colonna ad esempio) inserire nell'HINT del componente la stringa abbinata a quella colonna (ad esempio da un banale array di stringhe).

In questo caso hai un solo handle per l'HINT (quello di default del componente).

Contraccambio gli Auguri.

Ciao
Titolo: Re:rxdbgrid
Inserito da: Avogadro - Dicembre 23, 2021, 05:53:54 pm
Il bug sembra collegato all' evento "onDrawColomnCell" che mi serve per mostare i decimali giusti *

Si rifarrano le 11 stasera per sanare questo bug

Pazienza, youtube con un po' di musica in sottofondo aiuterà ...



*
in pratica i decimali delle misure variano in funzione della misura, una corretta formattazione dei numeri rende leggibili (ed utili) le tabelle

ora la cosa funziona sulla classica dbgrid di lazarus, ma non sulla rxdbgrid - vai a capire il perchè - ; in ogni caso  mi pare che questo evento fosse deprecato

questo era il semplcie frammento di codice ,  levandolo dall' ipesttore degli oggetti tutto torna normale

var
      fs: string;
begin
   fs:=ztable2format.AsString;
   if (isemptystr(fs,[' '])=true) then
      fs:='0.000' ;
   if ((column.FieldName='XM') or (column.FieldName='R') or (column.FieldName='RM')) then
      column.DisplayFormat:=fs ; 

end;

ma pensa te

Titolo: Re:rxdbgrid
Inserito da: DragoRosso - Dicembre 23, 2021, 06:14:44 pm
Questo è un esempio di cosa faccio io per disegnare in modo proprietario su una griglia:

Codice: [Seleziona]
procedure TFMain.SG_RisultatiDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var recttemp: TRect;
    tempMisura: TMisura;
    s1,s2: string;
begin
  if ARow > Elenco_Misure.Count then
    exit;
  if (ACol = 0) and (ARow > 0) then
    (Sender as TStringGrid).Canvas.TextOut(Rect.Left + 2, Rect.Top + (Rect.Height div 3), ARow.ToString);
  if (ACol = 2) and (ARow >= 1) then
    begin
      tempMisura := Elenco_Misure.Element[Arow-1];
      if Tarocco and (ARow = TaroccoMis) then
        begin
          s1 := '+0.000';
          s2 := '-0.000';
        end
      else
        begin
          if fControlloCampioneVISU then
            begin
              var ntp := abs(tempMisura.nTollPositiva / 10);
              if ntp < 0.015 then
                begin
                  ntp := 0.015;
                end;
              var ntn := abs(tempMisura.nTollNegativa / 10);
              if ntn < 0.015 then
                begin
                  ntn := 0.015;
                end;
              s1 := Format('+%.3f', [ntp], LocalFormat);
              s2 := Format('-%.3f', [ntn], LocalFormat);
            end
          else
            begin
              s1 := Format('+%.3f', [tempMisura.nTollPositiva], LocalFormat);
              s2 := Format('-%.3f', [abs(tempMisura.nTollNegativa)], LocalFormat);
            end;
        end;
      recttemp := Rect.SplitRect(srTop, 0.50);
      if (not tempMisura.bRisultato_Measure_P) and tempMisura.bDatiValidi then
        begin
          (Sender as TStringGrid).Canvas.Brush.Color := clRed;
        end
      else
        begin
          if (not tempMisura.bRisultato_Measure_N) and tempMisura.bDatiValidi then
            (Sender as TStringGrid).Canvas.Brush.Color := clWebLightPink;
        end;
      (Sender as TStringGrid).Canvas.FillRect(Recttemp);
      (Sender as TStringGrid).Canvas.TextOut(Recttemp.Left + 2, Recttemp.Top + 2, s1);
      recttemp := Rect.SplitRect(srBottom, 0.50);
      if (not tempMisura.bRisultato_Measure_N) and tempMisura.bDatiValidi then
        begin
          (Sender as TStringGrid).Canvas.Brush.Color := clRed;
        end
      else
        begin
          if (not tempMisura.bRisultato_Measure_P) and tempMisura.bDatiValidi then
            (Sender as TStringGrid).Canvas.Brush.Color := clWebLightPink;
        end;
      (Sender as TStringGrid).Canvas.FillRect(Recttemp);
      (Sender as TStringGrid).Canvas.TextOut(Recttemp.Left + 2, Recttemp.Top + 2, s2);
      exit;
    end;
  if (ACol >= 1) and (ARow >= 1) then
    begin
      tempMisura := Elenco_Misure.Element[Arow-1];
      if Tarocco and (ARow = TaroccoMis) then
        begin
        case ACol of
          1: begin
               s1 := '0.000';
             end;
          3: begin
               (Sender as TStringGrid).Canvas.Font.Style := [fsBold];
               if tempMisura.bDatiValidi then
                 s1 := '0.000'
               else
                 s1 := 'n.a.';
             end;
          4: begin
               (Sender as TStringGrid).Canvas.Font.Style := [fsBold];
               if tempMisura.bDatiValidi then
                 s1 := '0.000'
               else
                 s1 := 'n.a.';
             end;
        end;
        end
      else
        case ACol of
          1: begin
              if fControlloCampioneVISU then
                begin
                  s1 := Format('%.3f', [tempMisura.nMisura_Camp], LocalFormat);
                end
              else
                begin
                  s1 := Format('%.3f', [tempMisura.nRiferimento], LocalFormat);
                end;
             end;
          3: begin
               (Sender as TStringGrid).Canvas.Font.Style := [fsBold];
               if tempMisura.bDatiValidi then
                 s1 := Format('%.3f', [tempMisura.nMisura], LocalFormat)
               else
                 s1 := 'n.a.';
             end;
          4: begin
               (Sender as TStringGrid).Canvas.Font.Style := [fsBold];
               if tempMisura.bDatiValidi then
                 s1 := Format('%.3f', [tempMisura.nDiff], LocalFormat)
               else
                 s1 := 'n.a.';
             end;
        end;
      if ((not tempMisura.bRisultato_Measure_P) OR (not tempMisura.bRisultato_Measure_N)) and tempMisura.bDatiValidi then
        (Sender as TStringGrid).Canvas.Brush.Color := clWebLightPink;
      (Sender as TStringGrid).Canvas.FillRect(Rect);
      (Sender as TStringGrid).Canvas.TextOut(Rect.Left + 2, Rect.Top + (Rect.Height div 3), s1);
    end;
end;

Il codice scrive dei dati preelaborati e presenti un array (sotto forma di record).

Magari il codice è un pò criptico, ma non è complesso da capire.

EDIT: Come appare la griglia in allegato.

Ciao
Titolo: Re:rxdbgrid
Inserito da: Avogadro - Dicembre 23, 2021, 06:26:40 pm
Ho risolto:

è bastato usare l'evento "onPrepareCanvas"

Ciao e grazie