* * * *

Privacy Policy

Blog italiano

Clicca qui se vuoi andare al blog italiano su Lazarus e il pascal.

Forum ufficiale

Se non siete riusciti a reperire l'informazione che cercavate nei nostri articoli o sul nostro forum vi consiglio di visitare il
Forum ufficiale di Lazarus in lingua inglese.

Lazarus 1.0

Trascinare un file nel programma
DB concetti fondamentali e ZeosLib
Recuperare codice HTML da pagina web
Mandare mail con Lazarus
Stabilire il sistema operativo
Esempio lista in pascal
File INI
Codice di attivazione
Realizzare programmi multilingua
Lavorare con le directory
Utilizzare Unità esterne
TTreeView
TTreeview e Menu
Generare controlli RUN-TIME
LazReport, PDF ed immagini
Intercettare tasti premuti
Ampliare Lazarus
Lazarus e la crittografia
System Tray con Lazarus
UIB: Unified Interbase
Il file: questo sconosciuto
Conferma di chiusura di un applicazione
Liste e puntatori
Overload di funzioni
Funzioni a parametri variabili
Proprietà
Conversione numerica
TImage su Form e Panel
Indy gestiore server FTP lato Client
PopUpMenu sotto Pulsante (TSpeedButton)
Direttiva $macro
Toolbar
Evidenziare voci TreeView
Visualizzare un file Html esterno
StatusBar - aggirare l'errore variabile duplicata
Da DataSource a Excel
Le permutazioni
Brute force
Indy 10 - Invio email con allegati
La gestione degli errori in Lazarus
Pascal Script
Linux + Zeos + Firebird
Dataset virtuale
Overload di operatori
Lavorare con file in formato JSON con Lazarus
Zeos ... dietro le quinte (prima parte)
Disporre le finestre in un blocco unico (come Delphi)
Aspetto retrò (Cmd Line)
Lazarus 1.0
Come interfacciare periferica twain
Ubuntu - aggiornare free pascal e lazarus
fpcup: installazioni parallele di lazarus e fpc
Free Pascal e Lazarus sul Raspberry Pi
Cifratura: breve guida all'uso dell'algoritmo BlowFish con lazarus e free pascal.
Creare un server multithread
guida all'installazione di fpc trunk da subversion in linux gentoo
Indice
DB concetti fondamentali e connessioni standard
Advanced Record Syntax
DB concetti fondamentali e DBGrid
DB concetti fondamentali e TDBEdit, TDBMemo e TDBText
Advanced Record Syntax: un esempio pratico
Superclasse form base per programmi gestionali (e non)
Superclasse form base per programmi gestionali (e non) #2 - log, exception call stack, application toolbox
Superclasse form base per programmi gestionali (e non) #3 - traduzione delle form
Superclasse form base per programmi gestionali (e non) #4 - wait animation
Un dialog per la connessione al database:TfmSimpleDbConnectionDialog
Installare lazarus su mac osx sierra
immagine docker per lavorare con lazarus e free pascal
TDD o Test-Driven Development
Benvenuto! Effettua l'accesso oppure registrati.
Luglio 01, 2022, 03:00:56 pm

Inserisci il nome utente, la password e la durata della sessione.

15 Visitatori, 2 Utenti

Autore Topic: l'uso dell form  (Letto 226 volte)

moessner

  • Newbie
  • *
  • Post: 27
  • Karma: +0/-0
l'uso dell form
« il: Aprile 20, 2022, 12:19:28 pm »
Salve a tutti,

sto cercando di utilizzare 2 form.

La principale    f_cla    che contiene una listbox e
una modale     f_ins_cla   che permette di inserire un nuovo   item con   listbox.Items.add ('aaa')

Nella form principale ho inserito dopo implementation l'uso della unit realtiva all form modale.

Quando dalla form modale cerco di inserire il nuovo item mi dice :

Errore    indentifier not found   relativo alla form principale. 

Immagino che essendo nella form modale  non la conosca.

Come posso risolvere la cosa ?

Grazie per l'aiuto fina da ora.ù
moessner - Mario Piva 

nomorelogic

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2623
  • Karma: +12/-3
Re:l'uso dell form
« Risposta #1 il: Aprile 20, 2022, 04:02:04 pm »
ciao

se ci mostri anche il codice che ti da errore ci aiuti ad aiutarti ;)

da quello che leggo usi la form modale per inserire un elemento nella listbox contenuta nella form principale...
probabilmente l'errore lo ottieni perché nella unit della form modale non hai messo in uses la form principale

mettere comunque la uses di cui sopra ti darà quasi sicuramente un altro errore (referenza circolare)
nel senso che se UnitB dipende da UnitA, allora UnitA non può dipendere da UnitB

generalmente i dialog usati per inserire i dati non dovrebbero avere in uses la unit del chiamante
quindi il suggerimento è quello di predisporre un metodo nella classe della form principale che:
- istanzia la form secondaria (quella modale) per inserire i dati
- se la form modale è confermata, si prelevano i dati dalla form modale e li si processa
- si distrugge l'istanza della form modale

prova in questo modo che riduci le dipendenze ed isoli le form per l'inserimento dati

ciao
nomorelogic


Edit:
esempio (non compilato)
Codice: [Seleziona]
implementation
uses FormPerDati;

procedure TForm1.AddElementInListBox;
var x: TFormPerDati;
begin
  x:=TFormPerDati.Create(self);
  try
    x.Caption :='Inserisci qualcosa';
    if x.ShowModal = mrOk then begin
       ListBox1.Items.Add(x.Edit1.Text);
    end;
  finally
     FreeAndNil(x);
  end;

end;



« Ultima modifica: Aprile 20, 2022, 04:12:54 pm da nomorelogic »
Imagination is more important than knowledge (A.Einstein)

moessner

  • Newbie
  • *
  • Post: 27
  • Karma: +0/-0
Re:l'uso dell form
« Risposta #2 il: Aprile 20, 2022, 04:42:25 pm »
Grazie per l'attenzione.
Vi allego le due unit, spero che bastino.

//______________________________________________
unit u_classi;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ComCtrls,
  Buttons, LCLType ;


type

  { Tf_cla }

  Tf_cla = class(TForm)
    bIns: TBitBtn;
    bDel: TBitBtn;
    lCla: TLabel;
    lb: TListBox;
    sb: TStatusBar;
    procedure bDelClick(Sender: TObject);
    procedure bInsClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure lbClick(Sender: TObject);

  private

  public

  end;

var
  f_cla: Tf_cla;

implementation

uses u_ed_cla ;

{$R *.lfm}

{ Tf_cla }

procedure Tf_cla.FormShow(Sender: TObject);
begin
  sb.simpleText := 'Totale classi : ' + intToStr ( lb.count );
  bDel.Enabled := false ;
end;

procedure Tf_cla.lbClick(Sender: TObject);
begin
   if ( lb.ItemIndex <> -1 ) then
     bDel.Enabled := true
   else
     bDel.Enabled := false ;
end;


//______________________________________________
procedure Tf_cla.bInsClick(Sender: TObject);
begin
  f_ins_cla.showModal ;
  f_ins_cla.free ;
end;

procedure Tf_cla.bDelClick(Sender: TObject);
var
  i : integer ;
begin
  for i:=0 to lb.items.count-1 do
    if lb.Selected then
      if messageDlg ('Importante', 'Sei sicuro di voler cancellare la classe selezionata ?', mtConfirmation,
              [mbYes, mbNo, mbIgnore],0) = mrYes
       then
         begin


           lb.Items.Delete (i);
         //  lb.Items.beginUpdate;
          // lb.Items.endUpdate;
         end ;
//  lb.refresh ;
end;

end.
           



unit u_ed_cla;

{$mode ObjFPC}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, Buttons,
  ComCtrls ;

type

  { Tf_ins_cla }

  Tf_ins_cla = class(TForm)
    bok: TBitBtn;
    bcal: TBitBtn;
    e_cla: TLabeledEdit;
    sb: TStatusBar;
    procedure bcalClick(Sender: TObject);
    procedure bokClick(Sender: TObject);
    procedure e_claChange(Sender: TObject);
  private

  public

  end;

var
  f_ins_cla: Tf_ins_cla;

implementation

{$R *.lfm}

{ Tf_ins_cla }

procedure Tf_ins_cla.e_claChange(Sender: TObject);
begin
  if ( e_cla.text = '' ) then
    bOk.enabled := false
  else
    bOk.enabled := true ;
end;

procedure Tf_ins_cla.bcalClick(Sender: TObject);
begin

//f_ins_cla.close ;
end;

procedure Tf_ins_cla.bokClick(Sender: TObject);
begin
  //f_cla.lb.item.Add ( e_cla.text ) ;
  f_ins_cla.close ;
end;

end.



Grazie ancora
moessner - mario piva

nomorelogic

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2623
  • Karma: +12/-3
Re:l'uso dell form
« Risposta #3 il: Aprile 20, 2022, 07:25:52 pm »
prova a dichiarare in Tf_ins_cla un puntatore di tipo TListBox

Codice: [Seleziona]
unit u_ed_cla;

{$mode ObjFPC}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, Buttons,
  ComCtrls ;

type

  { Tf_ins_cla }

  Tf_ins_cla = class(TForm)
    bok: TBitBtn;
    bcal: TBitBtn;
    e_cla: TLabeledEdit;
    sb: TStatusBar;
    procedure bcalClick(Sender: TObject);
    procedure bokClick(Sender: TObject);
    procedure e_claChange(Sender: TObject);
  private

  public
     riferimento_lb: TListBox:   //   <---- aggiunta questa dichiarazione
  end;

var
  f_ins_cla: Tf_ins_cla;

implementation

{$R *.lfm}

{ Tf_ins_cla }

procedure Tf_ins_cla.e_claChange(Sender: TObject);
begin
  if ( e_cla.text = '' ) then
    bOk.enabled := false
  else
    bOk.enabled := true ;
end;

procedure Tf_ins_cla.bcalClick(Sender: TObject);
begin

//f_ins_cla.close ;
end;

procedure Tf_ins_cla.bokClick(Sender: TObject);
begin
  riferimento_lb.items.Add ( e_cla.text ) ;     // <- usi la listbox del form principale tramite il puntatore
  f_ins_cla.close ;
end;

end.

poi, nel sorgente della form principale:
Codice: [Seleziona]
procedure Tf_cla.bInsClick(Sender: TObject);
begin
  f_ins_cla.riferimento_lb := self.lb ;     //    <--- prima di lanciare la form secondaria, valorizzi il puntatore alla TListBox
  f_ins_cla.showModal ;
  f_ins_cla.free ;
end;


non ho provato il codice ma penso che sia semplice da capire come sistemare
resta comunque valido il consiglio della prima risposta ;)



Edit:
credo che se clicchi per la seconda volta sul bottone, dovresti ottenere un errore in quanto al primo passaggio distruggi l'istanza con la Free
« Ultima modifica: Aprile 20, 2022, 07:27:45 pm da nomorelogic »
Imagination is more important than knowledge (A.Einstein)

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 625
  • Karma: +11/-0
  • Prima ascoltare, poi decidere
Re:l'uso dell form
« Risposta #4 il: Aprile 21, 2022, 12:32:22 am »
mettere comunque la uses di cui sopra ti darà quasi sicuramente un altro errore (referenza circolare)
nel senso che se UnitB dipende da UnitA, allora UnitA non può dipendere da UnitB

Per evitare quello che dici, basta mettere le Uses nella sezione implementation. In quel caso non vengono generati riferimenti circolari, in quanto viene usata la unit esclusivamente per riferimento in compilazione. Nella sezione Interface non possono esserci riferimenti circolari.

Se uso una unità in Interface, l'altra unità può riferirsi alla prima solo nella sezione IMPLEMENTATION.

In genere, se il progetto viene ben costruito, ben poche unità del progetto andranno nella sezione Interface di altre, in genere solo perchè queste unità definiscono ad esempio tipi nuovi comuni nell'intero progetto, oppure costanti ad uso globale.

L'unità di riferimento di una "dialog" o una "form modale" non è detto che debba essere inserita nella sezione Interface, anzi in genere non ha molto senso.

E non serve neanche "distruggere" le istanze, a meno che l'occupazione di memoria non sia un problema. L'istanza della Form2 ad esempio esiste sempre, solo che viene nascosta alla chiusura. Ad ogni chiamata non ne vengono istanziate di nuove.

L'unica accortezza è che nell'evento Show della Form2 "form modale" è utile andare ad "azzerare" tutti i campi testuali o di immissione che sono eventualmente presenti al fine di non visualizzare dati magari presenti dalla precedente chiamata non coerenti.

Unit1
Codice: [Seleziona]
unit Unit1;

{$mode objfpc}{$H+}

interface     

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

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

Uses Unit2;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.ShowModal;
end;

end.

Unit2
Codice: [Seleziona]
unit Unit2;

{$mode ObjFPC}{$H+}

interface

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

type

  { TForm2 }

  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private

  public

  end;

var
  Form2: TForm2;

implementation

{$R *.lfm}

Uses Unit1;

{ TForm2 }

procedure TForm2.Button1Click(Sender: TObject);
begin
  Form1.ListBox1.AddItem('Pippo', self);
  Close;
end;

end.

In genere, quello che viene fatto nella Unit2 non è proprio il massimo, è sempre bene evitare di aggiornare un componente del chiamante con chiamata diretta (anche se è consentito e lecito) quando si è in modalità modale ... possono accadere delle cose non proprio bellissime.
Questo perchè il "motore dei messaggi di Windows", chiamata anche "pompa" ... qui sono grezzo al massimo ... rimane parzialmente "inchiodata" quando si è in modalità modale (la Form2 comanda, la Form1 è in una specie di stasi) e quindi qualsiasi interazione con la Form1 potrebbe non produrre i risultati attesi.

Anche per il tramite del "puntatore" come indicato da @nomorelogic si soffre della stessa "problematica".

Sarebbe cosa buona in realtà che le due form si scambino ad esempio delle "aree" di memoria (di qualsiasi tipo: record, array, etc ..) e la Form1 con la risposta OK della Form2 esegua l'elaborazione dei dati.

Spero di essere stato esauriente.

Ciao
« Ultima modifica: Aprile 21, 2022, 01:44:53 am da DragoRosso »
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

 

Recenti

How To

Utenti
Stats
  • Post in totale: 16432
  • Topic in totale: 2007
  • Online Today: 24
  • Online Ever: 900
  • (Gennaio 21, 2020, 08:17:49 pm)
Utenti Online
Users: 2
Guests: 15
Total: 17

Disclaimer:

Questo blog non rappresenta una testata giornalistica poiché viene aggiornato senza alcuna periodicità. Non può pertanto considerarsi un prodotto editoriale ai sensi della legge n. 62/2001.