14
Pagina 1 A. Veneziani – Elementi di programmazione con interfacce grafiche IDE di sviluppo grafiche Quasi tutte gli ambienti di sviluppo grafico per programmazione di applicazioni desktop tradizionali sono ormai basati su una comune impostazione che negli anni si è rivelata pratica e capace effettivamente di aumentare la capacità di programmazione del programmatore. Un elemento fondamentale per migliorare lo sviluppo è stato quello di integrare le varie fasi dello stesso in un unico tool che le rendesse sincroniche e facili da richiamare, così come possibile passare velocamente dall’una all’altra. In questo senso si cominiciò tanti anni fà a parlare di IDE di sviluppo, piuttosto che di semplici compilatori e tool di sviluppo. Una IDE era qualcosa che integrava in modo armonico i vari tool permettendone un uso più veloce ed ottimizzato, e di richiamare ed utilizzare le varie fasi tipiche dello sviluppo in modo assai più veloce. Questo passaggio si ebbe, almeno a livello di software commerciale, con l’apparizione di prodotti tipo il Turbo Pascal della Borland, quindi già nei primi anni ’80. Un altro passo importante fù quello di dotare tali ambienti integrati di ulteriori funzionalità che fossero di ausilio alla programmazione. La principale di queste, che ancor oggi è assai importante, è la presenza di funzionalità di debugging sempre più avanzate. Nei vecchi tool di sviluppo, esistevano già dei debugger, ma essi erano di uso poco intuitivo ed erano staccati dal resto dei tool di programmazione. Successivamente i debugger vennero profondamente integrati nelle IDE e ne divennero una parte fondamentale e sempre più evoluta, permettendo una individuazione degli errori sempre più comoda e veloce, oltre e rendere spesso possibile un apprendimento del linguaggio e del suo comportamento più veloce e chiaro nel settore educational. Infine all’inizio degli anni ’90 si ebbe un ulteriore step evolutivo. Sul computer più diffuso del momento, il PC, appare il primo sistema operativo con interfaccia grafica a larga diffusione: Windows 3.0. Pur con tutta una serie di limiti dovuti alla relativa parentela con DOS e limitazioni dovute alla sua architettura, questo sistema operativo impone di introdurre massicciamente la programmazione “a finestre” o con interfaccia grafica anche sul PC, la macchina più diffusa del mondo. In un primo momento tale programmazione è complessa e solo per “addetti ai lavori”, ma successivamente appaiono via via tools che permettono con facilità sempre crescente di creare applicazioni desktop grafiche. Il principe fra questi tool è senz’altro Visual Basic della stessa Microsoft, che già agli inizi degli anni ’90 propone un procedimento di programmazione dell’ interfaccia grafica molto intuitivo e veloce, dove altrimenti il programmatore avrebbe dovuto scrivere numerose linee di codice, da modificare e ritoccare magari spesso. Si parla comunemente da quel momento di programmazione “visuale”, per indicare un tipo di procedimento che si avvale di tool appositi, di solito interni alla IDE di sviluppo, per disegnare (nel vero senso del termine) una interfaccia grafica che poi sarebbe stata collegata al codice sottostante di programma. Questo paradigma di sviluppo poi accettato universalmente da tutte le IDE (da Netbeans a Visual Studio a molte altre), ha potenziato e velocizzato molto la parte di disegno grafico dei programmi. Altri ausilii, ormai irrinunciabili, sono le funzionalità di autocompletamento del codice, spesso utilissime come promemoria del programmatore. Il sistema di sviluppo suggerisce quali scelte possa fare il programmatore mentre stà scrivendo codice. Numerose altre sono le funzionalità di una IDE moderna, ma sostanzialmente essa deve essere vista come un raggruppamento di strumenti, ormai estremamente evoluto.

A. Veneziani Elementi di programmazione con interfacce ... · ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che ... raggruppare l’interfaia,

Embed Size (px)

Citation preview

Page 1: A. Veneziani Elementi di programmazione con interfacce ... · ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che ... raggruppare l’interfaia,

Pagina 1

A. Veneziani – Elementi di programmazione con interfacce grafiche

IDE di sviluppo grafiche

Quasi tutte gli ambienti di sviluppo grafico per programmazione di applicazioni desktop tradizionali sono

ormai basati su una comune impostazione che negli anni si è rivelata pratica e capace effettivamente di

aumentare la capacità di programmazione del programmatore.

Un elemento fondamentale per migliorare lo sviluppo è stato quello di integrare le varie fasi dello stesso in

un unico tool che le rendesse sincroniche e facili da richiamare, così come possibile passare velocamente

dall’una all’altra. In questo senso si cominiciò tanti anni fà a parlare di IDE di sviluppo, piuttosto che di

semplici compilatori e tool di sviluppo. Una IDE era qualcosa che integrava in modo armonico i vari tool

permettendone un uso più veloce ed ottimizzato, e di richiamare ed utilizzare le varie fasi tipiche dello

sviluppo in modo assai più veloce.

Questo passaggio si ebbe, almeno a livello di software commerciale, con l’apparizione di prodotti tipo il

Turbo Pascal della Borland, quindi già nei primi anni ’80.

Un altro passo importante fù quello di dotare tali ambienti integrati di ulteriori funzionalità che fossero di

ausilio alla programmazione. La principale di queste, che ancor oggi è assai importante, è la presenza di

funzionalità di debugging sempre più avanzate.

Nei vecchi tool di sviluppo, esistevano già dei debugger, ma essi erano di uso poco intuitivo ed erano

staccati dal resto dei tool di programmazione. Successivamente i debugger vennero profondamente

integrati nelle IDE e ne divennero una parte fondamentale e sempre più evoluta, permettendo una

individuazione degli errori sempre più comoda e veloce, oltre e rendere spesso possibile un apprendimento

del linguaggio e del suo comportamento più veloce e chiaro nel settore educational.

Infine all’inizio degli anni ’90 si ebbe un ulteriore step evolutivo. Sul computer più diffuso del momento, il

PC, appare il primo sistema operativo con interfaccia grafica a larga diffusione: Windows 3.0. Pur con

tutta una serie di limiti dovuti alla relativa parentela con DOS e limitazioni dovute alla sua architettura,

questo sistema operativo impone di introdurre massicciamente la programmazione “a finestre” o con

interfaccia grafica anche sul PC, la macchina più diffusa del mondo.

In un primo momento tale programmazione è complessa e solo per “addetti ai lavori”, ma successivamente

appaiono via via tools che permettono con facilità sempre crescente di creare applicazioni desktop grafiche.

Il principe fra questi tool è senz’altro Visual Basic della stessa Microsoft, che già agli inizi degli anni ’90

propone un procedimento di programmazione dell’ interfaccia grafica molto intuitivo e veloce, dove

altrimenti il programmatore avrebbe dovuto scrivere numerose linee di codice, da modificare e ritoccare

magari spesso.

Si parla comunemente da quel momento di programmazione “visuale”, per indicare un tipo di

procedimento che si avvale di tool appositi, di solito interni alla IDE di sviluppo, per disegnare (nel vero

senso del termine) una interfaccia grafica che poi sarebbe stata collegata al codice sottostante di

programma.

Questo paradigma di sviluppo poi accettato universalmente da tutte le IDE (da Netbeans a Visual Studio a

molte altre), ha potenziato e velocizzato molto la parte di disegno grafico dei programmi.

Altri ausilii, ormai irrinunciabili, sono le funzionalità di autocompletamento del codice, spesso utilissime

come promemoria del programmatore. Il sistema di sviluppo suggerisce quali scelte possa fare il

programmatore mentre stà scrivendo codice.

Numerose altre sono le funzionalità di una IDE moderna, ma sostanzialmente essa deve essere vista come

un raggruppamento di strumenti, ormai estremamente evoluto.

Page 2: A. Veneziani Elementi di programmazione con interfacce ... · ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che ... raggruppare l’interfaia,

Pagina 2

Le famiglie di componenti

Un sistema operativo, come forse avrete già sperimentato, ha molteplici modi di essere programmato.

Come prima differenza esistono vari linguaggi che permettono la programmazione del sistema operativo

stesso. Molti tra l’altro permettono di programmare in modo e con sintassi simili, sistemi operativi

differenti, ottenendo gli stessi risultati.

Un altra fonte di differenze è che le interfacce grafiche vengono di solito programmate con serie di

componenti che vanno a formarle e dare loro le funzionalità necessarie o previste.

In realtà questo strato software a componenti (basato totalmente sulla programmazione ad oggetti), non è

univoco, vale a dire non esiste una serie di componenti per Windows, ma bensì più serie e lo stesso vale

anche per Linux e gli altri sistemi operativi.

Esistono quindi varie serie di componenti “grafici”, tra loro usualmente non compatibili. Si potrebbe

parlare più giustamente di famiglie di componenti grafici. Di solito in ongnuna di tali famiglie esiste una

serie di componenti di base considerata per uso “standard” e poi un’altra serie più o meno numerosa di

componenti aggiuntivi che permettono speciali funzionalità. Questi componenti aggiuntivi in alcune

famiglie di componenti sono numerossissimi e spesso programmati da società terze che si occupano solo di

questo compito.

Così ogni “piattaforma” o linguaggio di sviluppo ha serie di componenti diversi e propri. Ad esempio Java

ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che

dipendono da esso ha le Windows Forms e alcune altre tecnologie sempre a componenti differenti, Delphi

e C++ Builder due linguaggi di notevole successo soprattutto in anni passati si basano ed utilizzano la

libreria di componenti detta VCL, in precedenza a .NET lo standard Microsoft per i componenti era quello

denominato ActiveX / COM, mentre nel mondo open, molte altre librerie di componenti sono disponibili a

seconda del linguaggio e tool di sviluppo utilizzato (ad esempio wxWidget e Qt o Lazarus (Object Pascal) con

i componenti LCL).

Queste famiglie di componenti differiscono tra loro per la metodica e alcuni standard propri della famiglia

stessa di componenti ed eventualmente dal linguaggio nel quale sono programamati. Questo fà si che

quasi sempre varie famiglie di componenti non siano utilizzabili per realizzare la stessa applicazione.

Tipicamente i componenti più comuni che si trovano in tutti i set di componenti grafici sono quelli base che

troviamo di continuo in una interfaccia grafica di un qualsiasi sistema operativo, quali pulsanti (button),

etichette (label), caselle di testo (textbox), liste a discesa (combobox), liste (listbox), caselle di spunta

(checkbox), pulsanti radio (radiobutton) ecc.

Il componente fondamentale però è sempre quello che permette di tenere assieme gli altri componenti e

raggruppare l’interfaccia, ossia la finestra (o form). I vari componenti vengono quindi disposti su di essa.

Componenti e programmazione ad oggetti

Inizia in questo periodo, ossia all’inizio degli anni ’90 la diffusione massiccia della programmazione ad

oggetti, dovuta al fatto che tutti gli elementi base di una interfaccia grafica sono degli oggetti, con loro

prorietà e metodi. E proprio per questo che l’ inizio dell’era della programmazione desktop con interfacce

grafiche, coindice con lo sviluppo e l’uso impetuoso di molteplici linguaggi basati sulla OOP (Object

Oriented Programming).

Anche linguaggi tradizionali attorno circa a questo periodo iniziano a trasformarsi ed integrare sempre

maggiori funzionalità ad oggetti, quali C (evolutosi in C++) e Pascal (evolutosi in diversi dialetti di Object

Pascal).

I programmi via via divengono più complessi e massicci e sempre più prende piede anche una

programmazione che si appoggia a librerie, perciò in questi sistemi operativi appare comune l’uso e

Page 3: A. Veneziani Elementi di programmazione con interfacce ... · ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che ... raggruppare l’interfaia,

Pagina 3

l’interazione con .DLL. Come noto, dopo qualche tempo, nascono nuovi linguaggi non direttamente

derivati da precedenti, e fortemente basati sulla OOP quali Java (1995) e successivamente C# (2000).

Un componente grafico quindi ha una sua apparenza grafica e nel contempo essendo un oggetto ha

proprietà, spesso legate al suo aspetto, e metodi per indurre modifiche e comportamenti dell’oggetto

stesso.

Un esempio di semplice progetto (C#)

Realizziamo ora un semplice esempio di programma con interfaccia grafica in C# e Visual Studio. Il

programma dovrà solo effettuare una somma tra interi e quindi sarà realizzato tramite tre label, tre box di

testo, e un pulsante, oltre che ad una form che contenga il tutto.

Le tre label (componente Label di Windows Forms), saranno opportunamente posizionate (magari sopra le

box di testo o al loro fianco a sinistra), e l’unica proprietà che verrà cambiata sarà la Text, tramite cui

cambierà la scritta all’ interno della label stessa. Per ottenenre le label selezioneremo il componente Label

nella Barra degli Strumenti e poi faremo click sulla form dove vorremo che il componente appaia. A questi

componenti dato che essi non verranno modificati (in quanto queste scritte sono fisse) e non interagiranno

con il programma potremo evitare di dare loro un nome specifico, quindi rimarrà quello di default dato da

Visual Studio.

Successivamente inseriremo sulla form tre box di testo (o caselle di testo) capaci di recepire input e di

svolgere anche funzioni di output. Nel caso del primo e secondo numero (i due addendi) ci servono per

recepire dati, mentre nel terzo caso, per il terzo elemento usato in output è possibile usare una box di testo

o una label indiferentemente.

Di queste modifichiamo la prorietà Name, dando un nome a dognuno di questi componenti, quali, txtAdd1,

txtAdd2, txtRisultato, di modo da poter individuare univocamente ogni componente. Poi modifichiamo la

proprietà Text di modo che la casella di testo all’inizio risulti vuota.

Di queste box potremo cambiare anche l’allineamento del testo per renderlo coerente con il trattamento di

dati numerici, quindi opereremo sulla proprietà TextAlign, selezionando il valore Right. Inoltre per la

Page 4: A. Veneziani Elementi di programmazione con interfacce ... · ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che ... raggruppare l’interfaia,

Pagina 4

txtRisultato potrà essere impostata la proprietà Readonly a True, dato che essa non deve servire da input di

dati, ma solo come visualizzazione di un risultato.

Successivamente si dispongono le textbox opportunamente sulla form. Gli allineamenti tra i componenti

saranno segnalati da apposite linee blu, del sistema di disegno dell’interfaccia.

Infine inseriremo sempre con la solita procedura un pulsante (Button), dando ad esso un testo (proprietà

Text), ad esempio “Somma”, modificando opportunamente posizione e dimensioni e associandogli un

nome diciamo btnSomma.

A questo punto non resta che operare qualche regolazione sulla form di base sulla quale i vari componenti

sono stati aggiunti. Di norma non è necessario variare il suo nome, ma semmai altri parametri tra cui:

Text – per inserire un nuovo titolo della form

Icon – per assegnare una nuova icona alla form (icona non presente se bordo fisso)

FormBorderStyle – per definire le proprietà del bordo della form. Varieremo questa

proprietà a FixedDialog, per far si’ che la form non abbia un bordo ridimensionabile.

MaximizeBox – a false per interdire la possibilità della form di essere massimizzata.

Dopo queste modifiche relativamente semplici, ed aver dimensionato opportunamente la nostra form, la

realizzazione della nostra interfaccia è terminata e quindi apprestiamoci a scrivere del codice C#.

Per far ciò selezioneremo la sezione Events (Eventi) della finestra Properties (Proprietà). Selezioneremo

quindi il componente pulsante e cercheremo l’evento Click che è quello che vogliamo associare al pulsante

stesso. Per confermare l’associazione basterà fare doppio click nella casella corrispondente dell’evento.

In essa apparirà una scritta corrispondente al nome della routine –evento (metodo), relativo all’evento.

Tale metodo verrà richiamato solo quando un evento di quel tipo accadrà su quell’elemento, nel nostro

progetto il pulsante Somma. A questo punto sarà apparso automaticamente del nuovo codice nel listato

del progetto (modulo di codice della form, denominato di default Form1.cs), ossia il metodo legato

all’evento Click.

In tale metodo andrà inserito il codice che deve essere eseguito alla pressione del pulsante, ossia quello che

effettua l’operazione di somma. Il metodo verrà richiamato quando l’evento click sarà effettuato sul

pulsante Somma.

Il codice che và inserito nel metodo è:

private void btnSomma_Click(object sender, EventArgs e) { int n1, n2, ris; n1 = Convert.ToInt32(txtAdd1.Text); n2 = Convert.ToInt32(txtAdd2.Text); ris = n1 + n2; txtRisultato.Text = Convert.ToString(ris); }

La comprensione del codice è piuttosto semplice.

a) Si dichiarano tre variabili intere utili al calcolo

b) Si legge il contenuto delle box di testo txtAdd1 e txtAdd2, assegnandolo alle var. n1 e n2

c) L’assegnazione, dato che le box txtAdd1 e txtAdd2 contengono stringhe deve essere preceduta da

una conversione.

d) La conversione di cui sopra in .NET avviene tramite una apposita classe detta Convert. Il metodo

ToInt32 passa ad un intero a 32 bit.

e) I valori scritti in txtAdd1 e txtAdd2 possono essere acquisiti e passano in n1 ed n2.

f) Viene effettuata la somma ed il risultato messo nella var. intera ris.

Page 5: A. Veneziani Elementi di programmazione con interfacce ... · ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che ... raggruppare l’interfaia,

Pagina 5

g) In questo caso il problema è inverso. Si ha un valore intero e si vuole renderlo visibile in

txtRisultato. txtRisultato può contenere solo testo (stringa).

h) Si utilizza ancora la Convert in questo caso con il metodo ToString che converte a stringa da intero.

In questo modo si ottiene nella box di testo txtRisultato il risultato voluto.

Lo stesso esempio in C++ Builder

C++ Builder è un potente ambiente RAD (Rapid Application Development) che permette velocemente e con

una certa semplicità di sviluppare applicazioni con interfaccia grafica, esso utilizza una versione

relativamente standard del linguaggio C++, con alcune estensioni proprietarie, dovute soprattutto alla

libreria VCL fulcro del sistema di programmazione di interfacce grafiche. Come tutti i RAD ed

analogamente a Visual Studio, C++ Builder utilizza la programmazione “visuale” dell’interfaccia, ossia dei

tools a due vie dove le modifiche alle proprietà hanno effetto (eventualmente) sul disegno dell’interfaccia e

modifiche al disegno vengono automaticamente recepite e registrate nelle relative ed opportune proprietà

degli oggetti che la costituiscono.

Come si vede anche in C++ Buider esiste la sezione per comporre e disegnare l’interfaccia grafica, quella per

regolare le proprietà, e la barra dei vari componenti (in questo caso della lbreria VCL).

Page 6: A. Veneziani Elementi di programmazione con interfacce ... · ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che ... raggruppare l’interfaia,

Pagina 6

Il procedimento è del tutto simile a quello indicato per il programma in C# con Visual Studio, ma cambia il

nome dei componenti e di alcune proprietà.

In questo caso la label, sarà indicata con Tlabel, che è poi la classe che definisce una label generica VCL.

La proprietà da regolare per cambiare il testo interno delle label in questo caso sarà denominata Caption.

Le text box in questo ambiente hanno nome TEdit. In questo progettino le sono state assegnate i valori

edtAdd1, edtAdd2, ed edtRis. Le proprietà da modificare per il nome saranno la Name e per regolare il

contenuto si agirà sulla proprietà Text.

Infine per rendere di sola lettura la edtRis, si opererà sulla proprietà Readonly (nome analogo a quello che

troviamo in .NET !) del componente edtRis.

Anche qui potremo regolare l’allineamento del testo nelle editbox (box di testo), cone la proporietà

Alignment, che dovrà essere regolata a taRightJustify.

Infine la form di base potrà essere regolata come in Visual Studio con le proprietà:

Caption – regola il titolo della form

Icon – regola l’icona della form

BorderStyle – serve per imporre alla form un bordo fisso. Regolato a bsSingle

BorderIcons -> biMaximize a False, per disattivare il tasto per massimizzare la form.

Successivamente si accede alla tab Events dell’Object Inspector e si associa un evento Click al pulsante

Somma, in modo del tutto simile a quello effettuato su Visual Studio.

Appare anche qui in modo automatico del codice C++ (anche qui sotto forma di metodo) dove inserire del

codice di programma.

void __fastcall TForm1::btnSommaClick(TObject *Sender)

{

int n1, n2, ris;

n1 = StrToInt(edtAdd1->Text);

n2 = StrToInt(edtAdd2->Text);

ris = n1 + n2;

edtRisultato->Text = IntToStr(ris);

}

Il significato della sintassi del metodo è che esso non rende valori (void), utilizza eventualmente e

preferenzialemente dei registri per il passaggio di valori dei parametri (__fastcall), e che la classe Tform1,

ha un metodo (definito al di fuori della classe stessa) di nome btnSommaClick. Il parametro Sender indica

chi è il componente (genericamente l’oggetto, quindi TObject) che ha chiamato la routine-evento.

In questo caso vediamo che C++ Builder mette a nostra disposizione funzioni di conversione diverse da

.NET. Esse fanno parte della libreria VCL, e trasformano AnsiString (una particolare forma di string propria

di VCL in intero) in intero StrToInt(...) e viceversa IntToStr(...). La proprietà Text permette come già detto

di accedere al testo delle caselle di testo (box di testo).

I principali componenti e le loro proprietà

Nei nostri programmi didattici useremo quasi sempre componenti “standard”, vale a dire quelli che in C++

Builder sono indicati nella tab “Standard” e in Visual C# nel gruppo di componenti “Common controls” o

componenti comuni, vale a dire pulsanti (button), caselle di testo (textbox), etichette (label), listbox,

Page 7: A. Veneziani Elementi di programmazione con interfacce ... · ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che ... raggruppare l’interfaia,

Pagina 7

combobox, pulsanti radio (radiobutton), caselle di spunta (checkbox), ed altri di uso comune su tutti sistemi

operativi con interfaccia grafica, specificamente Windows, Linux e Mac OS.

Esiste poi in tutti i linguaggi “visuali”, un altro componente che agisce come substrato (o contenitore) per

gli altri, vale a dire il form (o finestra). Un programma grafico, come ben noto può essere costituito da più

form, i quali possono entrare in azione in momenti diversi dell’esecuzione del programma stesso.

Per inserire uno di questi componenti sulla form, si seleziona lo stesso dalla barra degli strumenti (toolbox)

e si riporta sulla form, dove è possibile ridimensionarlo e riposizionarlo a piacere.

Queste operazioni regolano automaticamente due importanti proprietà del componente stesso, vale a dire

Top (distanza dall’alto della form, senza contare la barra del titolo) e Left (distanza dal bordo sinistro della

form) per il riposizionamento, e Width (larghezza del componente) ed Height (altezza del componente) per

il ridimensionamento1.

Tutti i componenti inseriti, soprattutto quelli che abbiano interazioni con il codice di programma, è

opportuno che abbiano un nome ben preciso e riassegnato dal programmatore. Il nome di un

componente, già presente con un valore di default, può essere riassegnato dal programmatore con la

proprietà Name (che ha lo stesso nome e scopo sia in Windows Form che nelle VCL). Essa permette di

ridenominare opportunamente ed in maniera più propria, rispetto agli scopi nel progetto, ogni componente

presente. Usualmente è buona norma indicare con una sigla (di solito di tre le lettere) la tipologia del

componente e poi affiancarne il nome vero e proprio. Ad esempio: lblValore, btnOk, txtContatore, ecc.

Questa regolazione manuale delle proprietà, come quelle di tutte le altre proprietà può essere fatta

inserendo valori nella apposita griglia delle proprietà, denominata in Visual C# (Proprietà o Properties) ed in

C++ Builder2 nella tab Properties della finestra Object Inspector.

Le proprietà indicate sopra hanno gli stessi nomi anche in C++ Builder e nella serie di componenti VCL.

Le proprietà possono venir modificate a design-time, ma ovviamente non durante l’esecuzione del

programma, dove solo il codice ha la capacità di influenzare il layout stesso.

A questo proposito bisogna tener presente che esistono tre stati possibili della IDE (sia in Visual Studio che

C++ Builder):

Design time - il programma è fermo ed è possibile disegnare l’interfaccia e regolare le proprietà dei

componenti

Run-time – Il programma è in esecuzione e NON è possibile disegnare o modificare l’interfaccia o

regolare le sue proprietà (ed in Visual C#, neppure modificare il codice)

Debug-time – Si tratta di uno stato particolare nel quale si effettua il debug del programma, ossia la

sua esecuzione controllata. In tale stato è possibile visionare il contenuto delle variabili, alterarne il

valore, visionare l’esecuzione in modalità passo-passo, osservando quali istruzioni vengano

eseguite.

Analizziamo in dettaglio quindi alcuni di questi componenti:

Altre proprietà comuni a vari controlli

Esistono altre proprietà che sono comuni a diversi controlli che si possono incontrare sulle interfacce. Tra

queste abbiamo analizzato:

Visible – permette la visibilità o meno di un componente (se è un componente visualizzabile

sull’interfaccia grafica). E’ booleana. E’ analoga e ha lo stesso effetto sia in Windows Form che VCL.

1 In Visual C# Top e Left sono utilizzabili nel codice di programma, al momento della regolazione manuale della posizione si deve utilizzare le componenti X e Y della proprietà Location. 2 Attualmente non esiste una versione italiana di C++ Builder, che è disponibile in Inglese e poche altre lingue.

Page 8: A. Veneziani Elementi di programmazione con interfacce ... · ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che ... raggruppare l’interfaia,

Pagina 8

Se il componente ha tale proprietà a false non è visibile a run-time (esecuzione) , mentre come logico lo è a

design time, ossia mentre si disegna / modifica l’interfaccia.

Enable – Indica che il componente è abilitato o meno. Un componente disabilitato è visibile, ma non

svolge le sue funzioni e non attiva gli eventuali eventi ad esso associati. Il controllo apparirà graficamente

con colori più sfumati in certi dettagli, quali scritte da colore nero a colore grigio ed effetti similari.

Form

E’ il componente fondamentale per la realizzazione di programmi con interfacce grafiche. Realizza le

famose “finestre”, sulle quali, grazie ad altri componenti, sono implementate le funzionalità volute. Funge

quindi da base per tutti gli altri componenti.

Anch’essa possiede le proprietà “universali”, Top, Left, Width ed Height, oltre che Name. In particolare il

valore di Top e Left si riferiscono però in questo caso al sistema di coordinate dello schermo, quindi sono

calcolate rispetto all’angolo in alto a sinistra dello schermo.

Di una form usualmente si desidera anche cambiare il titolo, e ciò può essere fatto tramite la proprietà:

Text (Visual C#)

Caption (C++ Builder)

Talora si vuole rendere la form con il bordo fisso (frequentemente in progettini semplici come i nostri).

Per far questo si dovrà alterare le proprietà:

FormBorderStyle cambiandola da Sizable a FixedSingle (in Visual C#)

BorderStyle cambiandola da bsSizable a bsSingle (C++ Builder)

Inoltre abbiamo visto che può essere utile eliminare la possibilità di massimizzare la finestra (form),

interdicendo il pulsante di massimizzazione della stessa, ossia regolando la proprietà:

MaximizeBox a false (Visual C#)

BorderIcons sottosezione biMaximize a false (C++ Builder)3

Inoltre in entrambi i sistemi di sviluppo (Visual C# e C++ Builder) è possibile modificare l’icona sulla form

tramite la modifica della proprietà Icon.

Label (Windows Form) / TLabel (VCL)

E’ un componente atto a visualizzare una scritta. Non permette la scrittura diretta da parte dell’utente, ma

solo, eventualmente, quella da parte del programma (quindi è un componente che può eventualmente,

essere usato per il solo output di dati.

Le principali proprietà del componente sono:

Text (Visual C#)

Caption (C++ Builder)

Per modificare la scritta stessa. Inoltre sia nelle VCL che in Windows Form, è abilitata di default la

proprietà Autosize, che ridimensiona automaticamente la label a seconda della scritta in essa presente.

Tale proprietà per vari motivi (ad esempio una label che inizialmente non contiene testo tende a divenire

poco visibile nel progetto grafico) può essere disabilitata (false).

Nel caso Autosize sia quindi a false la label può essere liberamente ridimensionata.

Inoltre abbiamo visto nel progetto dell’orologio che è possibile (come del resto in altri controlli) modificare

la dimensione e il font del testo della label, regolando:

Font sottosezione Name

Font sottosezione Size (in Visual C#)

Page 9: A. Veneziani Elementi di programmazione con interfacce ... · ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che ... raggruppare l’interfaia,

Pagina 9

E

Font sottosezione Name

Font sottosezione Size (in C++ Builder)

Specifico che la regolazione di tali proprietà è meccanica ed intuitiva tramite l’’interfaccia grafica a design

time, ma un po’ più complessa e meno ovvia se si dovesse effettuare via codice. Ecco due spezzoni di

programma che regolano gli stessi aspetti in C# e C++ Builder: label1.Font = new Font("Consolas", 20); // Visual C#

e

this->Label1->Font->Name = "Consolas";

this->Label1->Font->Size = 20; // C++ Builder

dove this è la form che ospita il componente (tlabel1 nel nostro caso).

E’ eventualmente possibile cambiare il colore di background di una label (cosa che potrebbe essere utile

per vari motivi), con le proprietà:

Per C++ Builder bisognerà regolare 2 proprietà:

1. Trasparent a false (regola la trasparenza del componente - fondo opaco o trasparente )

2. Color al valore del colore voluto

Usualmente i colori stadard in C++ Builder sono costanti predefinite il cui nome inizia con cl…., ad esempio

clRed, cl Yellow, ecc..

Per Visual C#:

Regolare la proprietà BackColor ad un colore voluto

Come si nota dopo la regolazione, la proprietà è definita da una terna di valori tra 0 e 255, ognuno dei quali

regola uno dei colori fondamentali R (rosso), G (verde), B (blu).

TextBox (Windows Form) / TEdit (VCL)

E’ un componente che permette all’utente di inserire dei dati (di default su una sola riga). Il suo

contenuto può anche essere scritto dal programma, e quindi si comporta come una zona dell’ interfaccia

per l’input-output di dati.

Se il desiderio del programmatore è che solo il programma possa scrivere nella casella di testo, si dovrà

regolare la proprietà Readonly a true (di default è a false). In questo caso non è più possibile scrivere dati

nel componente ed esso diviene di solo output (in modo simile alla Label).

La proprietà Readonly (booleana) è presente con lo stesso nome e significato sia in Windows Form che il

VCL.

Per alterare o leggere il testo del componente casella di testo (TextBox in Windows Form, TEdit in VCL), si

utilizza la proprietà Text (con lo stesso nome e significato sia in Windows Form che in VCL).

In alcuni progettini abbiamo modificato l’allineamento delle textbox dato che esse erano destinate a

contenere valori numerici (di solito allineati a destra), mentre l’allineamento di default delle textbox / tedit

è a sinistra (previsto per dati alfanumerici di tipo generico).

Per modificare tale aspetto esiste una apposita prorietà:

TextAlign (di default a left) da portare a right (Visual C#)

Alignment (di default a taLeftJustify) che và portata a taRightJustify (C++ Builder)

E’ possibile variare il colore della textbox / tedit con:

Proprietà Color (in C++ Builder)

Proprietà BackColor (Visual C#)

Page 10: A. Veneziani Elementi di programmazione con interfacce ... · ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che ... raggruppare l’interfaia,

Pagina 10

Button (Windows Form) / TButton (VCL)

Si tratta del comune pulsante o bottone, di cui sono piene le finestre di Windows e altri sistemi operativi.

Le dimensioni e posizione sono regolabili con le proprietà generali di cui si è parlato in precedenza.

La scritta sul pulsante che descrive le sue funzionalità viene modificata tramite la proprietà:

Text (in Visual C#)

Caption (in C++ Builder)

Ovviamente anche nei pulsanti possono essere variate le proprietà Enabled e Visible, con gli effetti detti in

precedenza.

Ai pulsanti è spesso frequente associare l’evento click, il più usato per questo tipo di componenti.

La metodica è simile sia per C++ Builder che per Visual C#:

1) Si seleziona il componente sulla form

2) Si assegna ad esso il nome desiderato con la proprietà Name

3) Ci si sposta su Object Inspector (C++ Builder) o sulla finestra Prorietà (Visual C#)

4) Si seleziona la tab Events dell’ Object Inspector (C++ Builder) o il pulsante apposito in Prorietà

(Visual C#)

5) Nella lista dei tipi di evento associabili al componente si cerca l’evento di tipo Click (OnClick per

C++ Builder) (Click per Visual C#)

6) Si effettua doppio click nella casella bianca di lato

7) Automaticamente il tipo di evento viene associato al componente e la relativa routine (metodo)

evento appare nel codice scritta in modo automatico

8) Aggiungere adesso il codice desiderato all’interno della routine evento, che dovrà essere eseguito

quando l’evento viene richiamato.

Radiobutton (Windows Form) / TRadioButton (VCL)

In un progetto proposto e realizzato come esercitazione di laboratorio è stata utilizzata una serie di pulsanti

radio, altrimenti detti in inglese radiobutton. Questi controlli operano in gruppo e la selezione di ognuno

di essi è alternativa alle altre dello stesso gruppo, vale a dire solo un radio di un certo gruppo può essere in

uno stato di selezione.

I controlli radio sia in Windows Form che in VCL hanno anche annessa una scritta abbinata al radio stesso,

esplicativa della voce selezionata.

Un solo gruppo di radio può essere utilizzato in modo piuttosto semplice. Basta posizionare i radiobutton

sulla form, dare loro dei nomi (diversi) e controllare il loro stato di selezione, tramite la proprietà Checked.

Tale proprietà è presente con lo stesso nome e significato sia In Windows Form che nelle VCL, ossia

permette di controllare se un certo radio sia o no selezionato.

Nel caso sulla form fosse necessario avere più gruppi indipendenti di radio, allora:

In Windows Form incolla prima uno speciale componente di raggruppamento detto GroupBox. Su

di esso si “incolla” il primo gruppo di radio. Si ripete l’operazione con altri eventuali gruppi. In tale

modo i vari gruppi agiscono in modo indipendente.

La proprietà Text del componente permette di regolare la scritta esplicativa del gruppo stesso di

componenti.

Una metodica del tutto simile si utilizza con la libreria di componenti VCL. Anche qui esiste uno

specifico componente capace di creare gruppi di radio e farli funzionare in modo indipendente,

esso è detto TGroupBox e fa parte della palette dei componenti Standard. Per aggiungere i

componenti radio al groupbox si selezionano i radio e si rilasciano sul groupbox. I componenti

radio all’ interno di ogni groupbox lavorano in modo indipendente.

Page 11: A. Veneziani Elementi di programmazione con interfacce ... · ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che ... raggruppare l’interfaia,

Pagina 11

La proprietà Caption del componente permette di regolare la scritta esplicativa del gruppo stesso di

componenti.

Timer (Windows Form) / TTimer (VCL)

E’ un componente che è stato utilizzato ad esempio nel progettino dell’orologio digitale. Si tratta di un

componente capace di produrre ciclicamente eventi ad intervalli di tempo predeterminati dal

programmatore. L’evento che può essere associato al Timer è uno solo ed è OnTimer nelle VCL e Tick in

Windows Form. Il componente TTimer si trova nel gruppo di componenti System in C++ Builder e Timer

nel gruppo Components in Visual C#.

Il componente Timer / TTimer non è mai visibile, quindi non è un componente grafico. Nonostante ciò, per

aggiungere lo stesso al progetto si opera come se esso fosse un componente come gli altri ossia visibile.

L’icona del componente è un orologio.

Il componente in Windows Form e anche nelle VCL possiede la proprietà Enabled, che è messa a false. Per

attivare il suo funzionamento si deve quindi portare a true tale proprietà, altrimenti il timer non produce gli

eventi ripetuti previsti.

La proprietà Interval ha lo scopo di indicare l’intervallo di tempo in millisecondi ogni quanto viene

richiamato l’evento del timer; essa ha lo stesso nome e scopo sia in Windows Form che in VCL.

Ovviamente anche il Timer ha una proprietà Name per dare ad esso uno specifico nome.

Per i componenti senza visibilità sull’interfaccia non hanno senso le proprietà Top, Left, Width ed Height.

PictureBox (Windows Form) / TImage (VCL)

Nel progettino in C# cui si doveva indovinare il numero segreto generato dal computer, abbiamo fatto uso

di due PictureBox. Questo componente è utilizzato in Windows Form per visualizzare immagini sulla form

stessa. Nel nostro caso abbiamo caricato l’immagine tramite la proprietà Image (Windows Form).

Poi abbiamo imposto all’immagine stessa di assumere le dimensioni stesse del controllo effettuando una

operazione di ridimensionamento / cambio delle proporzioni , detta strech. Questa operazione è attivata

in questo controllo dalla proprietà SizeMode messa a StrechImage (noermalmente essa è a Normal).

In questo modo abbiamo costretto l’immagine originale a ridimensionarsi fino a essere completamente

visibile nel controllo.

Nel caso di C++ Builder si può utilizzare un componente del tutto equivalente detto TImage (sezione dei

componenti aggiuntivi). Il componente viene ridimensionato e posizionato, poi con la proprietà Picture

sarà possibile caricare l’immagine voluta e visualizzarla. La proprietà Strech del controllo effettua lo strech

dell’ immagine caricata se posta a true.

La proprietà Visibile, permette di regolare la visibilità dell’immagine caricata, senza scaricarla dal controllo.

Box di messaggio

Non sono dei veri componenti, ma sono delle particolari form (di solito che appaiono in modalità modale4),

atte a mostrare messaggi all’utilizzatore del programma (grafico).

In questa sezione, in base a quanto utilizzato anche nei progettini fin qui affrontati, considereremo solo box

di messaggio con un solo pulsante di conferma (Ok), nelle quali non essendoci alternative, non si pone il

problema di comprendere quale pulsante sia stato premuto prima di chiudere la form di messaggio.

4 Una form è in modalità modale, se essa, una volta apparsa, è l’unica form del programma su cui può operare l’utente. Lo stato del programma, in background, resta “congelato”, in quanto l’utente non può accedere a nessuna delle funzionalità delle form in background finchè non chiude la form principale.

Page 12: A. Veneziani Elementi di programmazione con interfacce ... · ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che ... raggruppare l’interfaia,

Pagina 12

In Visual C# si producono con metodi cha appartengono ad una apposita classe MessageBox, preposta a

generare tali form in molte forme e varianti.

Il metodo che viene usato per produrre box di messaggio è lo Show, che a seconda

del numero di parametri indicati produce finestre con caratteristiche diverse.

Ad esempio l’istruzione: MessageBox.Show("Semplice messaggio", "Titolo");

crea una semplice MessageBox con solo messaggio e titolo, mentre la specifica di

alcuni altri parametri consente di avere delle box con tutte le caratteristiche: MessageBox.Show("Semplice messaggio", "Titolo",MessageBoxButtons.OK, MessageBoxIcon.Information);

Da notare che i valori di combinazioni di pulsanti e delle icone sono propri di

apposite enumerazioni MessageBoxButtons che contiene diversi possibili valori

quali Ok, OkCancel, YesNo, ed altri e MessageBoxIcon, che contiene costanti che

definiscono il possibile tipo di icona, quali Information, Question, Warning ed altri.

In C++ Builder sono utilizzate due funzioni VCL per produrre delle finestre di messaggio:

ShowMessage – Crea una form con il solo pulsante Ok e una scritta esplicativa. La form di

messaggio non ha icona ed il titolo non è

regolabile. Ha un solo parametro, ossia il

testo da scrivere.

ShowMessage(“Questo e’ il messaggio”);

MessageDlg – Permette di creare form di

messaggio più articolate e con più elementi regolabili, tra cui un icona, il numero e tipo di pulsanti.

Ha 5 parametri:

o Messaggio

o Icona (del tipo di messaggio)

o Pulsanti da visualizzare

Il quarto parametro relativo all’help contestuale, per scopi comuni, viene di solito messo a 0.

Ad esempio il comando C++ Builder:

MessageDlg("Messaggio da

comunicare",mtInformation,TMsgDlgButtons() <<

mbOK, 0);

produce una MessageBox di questo tipo:

Il titolo di queste form riflette la tipologia di icona

applicata.

Conversioni comuni in C++ Builder e Visual C#

Come abbiamo visto nel corso della realizzazione dei progettini, alcuni tipi di conversione sono

estremamente comuni nei programmi con interfaccia grafica. Mi riferisco in particolare a quelle relative

alla conversione da interi a alfanumerico equivalente ad un numero intero o l’analoga da intero a valore

float.

Queste conversioni sono frequenti perché al contrario che nei programmi console, sia C++ che C# scrivono

e leggono con valori alfanumerici dall / sull’interfaccia e quindi è sempre necessaria una conversione dei

valori stessi.

In C# le conversioni sono gestite tramite la classe Convert. Essa utilizza dei metodi statici per effettuare i

vari tipi di conversione. Nel nostro codice infatti non si istanziano oggetti della classe Convert, ma essa

Page 13: A. Veneziani Elementi di programmazione con interfacce ... · ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che ... raggruppare l’interfaia,

Pagina 13

viene utilizzata direttamente. Il metodo acquisisce come parametro il valore originario e rende un risultato

che è il tipo di valore desiderato.

Le conversioni, in questo caso sono effettuate da apposite funzioni VCL StrToInt(…) e viceversa IntToStr(…)

preposte a convertire interi con stringhe e viceversa. Nella libreria VCL sono a disposizione numerose

funzioni per effettuare conversioni quali StrToDate e DateToStr o StrToFloat e FloatToStr, ed altre.

Gestione degli errori in C# e C++ Builder

In alcuni listati abbiamo visto esempi di utilizzo di operazioni dotate di controllo su eventuali errori

dovessero accadere durante l’esecuzione del codice.

In particolare un esempio di semplice controllo di errore è facilmente applicabile al nostro programma che

effettua la somma, riportato nei primi paragrafi di questa dispensa.

In particolare il punto dove ovviamente potrebbero accadere delle situazioni di errore sono le conversioni

dei valori letti dalle box di testo, ove l’utente ha inserito i due addendi.

Tali conversioni sono da alfanumerico a numerico (abbiamo presunto i numeri siano interi).

Due sono i possibili motivi di errore:

L’utente non inserisce alcun dato

L’utente inserisce dati non convertibili (ad. es. la stringa “abc” o altra) in un numerico intero

In ambiente .NET questa situazione produce subito una eccezione che viene segnalata da una apposita

finestra mentre il programma stà girando.

Una cosa simile con analoga modalità avviene quando l’eseguibile C++ Builder incorre in un errore di

conversione. In questi casi però il motivo della situazione di errore non viene esplicitato, e quindi è

difficile capire cosa sia successo e quale sia la causa effettiva di errore.

In questo caso si può decidere di realizzare una gestione custom dell’errore stesso che aiuti a comprendere

con più precisione quale sia la causa del problema e a segnalarlo all’utente in modo semplice.

Il controllo di errore sia in C# che in C++ viene fatto attraverso il costrutto sintattico try….catch….

Nella parte try si mettono le istruzioni da controllare, ossia si controlla se esse producano errori, mentre

nella parte catch, oltre ad un filtro sulla tipologia/e di errore “catturata”, si predispongono le operazioni

che devono essere svolte quando l’errore si verifica ed è del tipo previsto dalla specifica istruzione catch.

Ad esempio per controllare errori di conversione relativi ai valori inseriti nelle box “Addendo 1” e “Addendo

2” del programma somma. Le conversioni normalmente effettuate in condizioni di dati corretti possono

viceversa fallire, e quindi produrre errori di run-time. A questo punto un frammento di codice del

seguente tipo può gestire qualunque errore legato al problema degli input errati:

int n1 = 0, n2 = 0, ris; bool errore = false; try { n1 = Convert.ToInt32(txtAdd1.Text); n2 = Convert.ToInt32(txtAdd2.Text); } catch (FormatException fe) { MessageBox.Show("Valori degli addendi non adeguati.", " - Errore - "); errore = true; } if (!errore) { ris = n1 + n2; txtRisultato.Text = Convert.ToString(ris);

Page 14: A. Veneziani Elementi di programmazione con interfacce ... · ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che ... raggruppare l’interfaia,

Pagina 14

}

In pratica il blocco try / catch entra in azione qui per motivi di dati non convertibili, ed allora viene

visualizzata una box di messaggio, oltre a non eseguire il codice successivo, ossia quello che effettuerebbe

la somma (ma non in questo caso mancando i dati). FormatException è il tipo di errore intercettato, e

questa eccezione viene prodotta quando vi sono problemi a convertire i dati di input verso il tipo intero

previsto.

Con una metodica del tutto simile si può affrontare il problema di gestire analoghi errori in C++ Builder,

tramite un controllo di errore gestito anche da apposite classi VCL.

Con una logica del tutto simile alla precedente il codice C++ Builder è:

int n1, n2, ris;

bool errore = false;

try {

n1 = StrToInt(edtAdd1->Text);

n2 = StrToInt(edtAdd2->Text);

}

catch (EConvertError &e)

{

ShowMessage("Dati inseriti non congruenti con l'operazione.");

errore = true;

}

if (! errore)

{

ris = n1 + n2;

edtRisultato->Text = IntToStr(ris);

}

Come è possibile vedere la logica dei due linguaggi è del tutto simile a parte qualche dettaglio sintattico.

Anche qui la parte che controlla se ci sono errori è il try e c’è l’attivazione del codice nella parte catch se

l’errore è della tipologia della classe indicata come parametro del catch. Il puntatore ad oggetto e,

permette di accedere ad alcune informazioni proprie dello specifico errore accaduto.

In questo caso la tipologia di eccezione corretta da usare è EConvertError. Si tratta di una classe preposta a

gestire errori di conversione, essa è una tipologia di errore la cui gestione è prevista dalle librerie VCL.

Altre classi di errore VCL sono elencate in:

http://docwiki.embarcadero.com/RADStudio/Tokyo/en/VCL_Exception_Classes