Qt Lezione3: un visualizzatore di immagini

9

Click here to load reader

description

Questa lezione sul toolkit Qt permette di scrivere una semplice applicazione di visualizzazione immagini, i formati sono quelli più comunemente usati: JPG, BMP, PNG etc.

Transcript of Qt Lezione3: un visualizzatore di immagini

Page 1: Qt Lezione3: un visualizzatore di immagini

Mini Guide Qt

Autore P. Sereno http://www.sereno-online.com/site

Creare un’applicazione di visualizzazioneimmagini

Premessa

Questa presentazione è rilasciata sotto Licenza Creative Commons: Attribution-NonCommercial-NoDerivativeWorks (http://creativecommons.org/licenses/by-nc-nd/3.0/deed.it).

Questo documento può quindi essere riprodotto senza violare nessuna legge, sia in versione elettronica, sia in versione cartacea, purché sia riprodotto integralmente in tutte le sue parti, compresa la pagina che contiene queste informazioni:

Versione originale scaricabile dal sitohttp://www.sereno-online.com/site/

Tutti i marchi riportati in questa pubblicazione appartengono ai rispettivi proprietari.

Link Utili

Qui di seguito riporto alcuni link utili per chi usa quotidianamente l’ambiente di sviluppo Qt e vuole confrontarsi con altri sviluppatore, utenti e semplici appassionati di questo toolkit gratuito ed open source.

Gruppo Programmatori Italiani Qt Software (GPIQt)

http://www.facebook.com/inbox/?ref=mb#/group.php?gid=81561439535

qt in Italy

http://qt-apps.org/groups/?id=17

qtitaliantranslators

http://gitorious.org/+qtitaliantranslators

Page 2: Qt Lezione3: un visualizzatore di immagini

Mini Guide Qt

Autore P. Sereno http://www.sereno-online.com/site

Scopo

Scopo di questa terza lezione è arricchire l’applicazione creata nella seconda lezione con alcune utili funzionalità. Il codice sorgente della terza lezione è reperibile sul sito http://www.sereno-online.com/sitealla pagina di downloads.

Questo esempio non vuole essere un’applicazione completa e con molte funzionalità, si vuole cioè evitare di sommare troppi concetti per un’unica lezione e si vuol lasciare al lettore la curiosità di scoprire nuove funzioni del Qt application framework.

I fondamenti di quest’applicazione sono presi da un progetto open source (QPhoton) il cui obiettivo è quello di realizzare un programma di fotoritocco semplice da usare e poco pesante.

Buon lavoro!

Passo 1

Per prima cosa partiamo dalla main window della seconda lezione (in altre parole, possiamo recuperare il codice sorgente della lezione numero 2), rappresentata nella figura qui sotto

Page 3: Qt Lezione3: un visualizzatore di immagini

Mini Guide Qt

Autore P. Sereno http://www.sereno-online.com/site

Passo 2

Aggiungiamo ora (in Qt Creator) una MDIArea alla nostra main window (MdiArea si trova nella toolbar a sinistra, subito dopo la lista files, alla voce Containers), il risultato dovrà essere più o meno così:

come si può osservare, l’area centrale della nostra main window è ora grigio scuro, questo perché è stata inserita la MDIArea.

Page 4: Qt Lezione3: un visualizzatore di immagini

Mini Guide Qt

Autore P. Sereno http://www.sereno-online.com/site

Passo 3

Scriviamo ora nel file mainwindow.cpp il codice seguente:

#include "ui_mainwindow.h"#include "mainwindow.h"#include <QAction>#include <QFileDialog>#include <QImageReader>#include <QList>#include <QString>#include <QLabel>#include <QPixmap>

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow){

ui->setupUi(this);connect(ui->actionOpen,SIGNAL(triggered()),this, SLOT(openFile()));

}

MainWindow::~MainWindow(){

delete ui;}

int MainWindow::openFile(){

QString fileName,currentPath;// set filters = all supported file formats. New plugins will automatically add new image formatsQList <QByteArray> supportedFilters;QString filters;QString defaultFilter;QImageReader reader;supportedFilters = reader.supportedImageFormats();defaultFilter.append(tr("Images ( "));

for (int i = 0; i < supportedFilters.size(); ++i) {

defaultFilter.append("*.");defaultFilter.append(supportedFilters[i].toUpper());defaultFilter.append(" ");filters.append(supportedFilters[i].toUpper());filters.append(" (*.");filters.append(supportedFilters[i]);filters.append(" );;");

}

defaultFilter.append(");;");filters.append(tr("Any File( * )"));filters.prepend(defaultFilter);fileName=QFileDialog::getOpenFileName(this,tr("Open"),currentPath,filters);

if (!fileName.isEmpty()) // if fileName is not empty{

child = new QLabel(0);child->setPixmap(fileName);ui->mdiArea->addSubWindow(child);child->show();

}

return 0;}

Page 5: Qt Lezione3: un visualizzatore di immagini

Mini Guide Qt

Autore P. Sereno http://www.sereno-online.com/site

Passo 4

Analizziamo nel dettaglio ogni singolo metodo.

Il costruttore:

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow){

ui->setupUi(this);connect(ui->actionOpen,SIGNAL(triggered()),this, SLOT(openFile()));

}

Fin qui nulla di nuovo rispetto la seconda lezione.

setupUI è il metodo incaricato di inizializzare l’intera interfaccia utente creata da Qt Creator.

connect realizza la connessione con la QAction di nome actionOpen del menu (File->Open) che abbiamo

creato da Qt Creator. Nella lezione 2 avevamo fatto una cosa analoga per la actionExit, ovvero il menu responsabile di chiudere l’aplicazione; ora abbiamo creato un altro menu (File->Open) per l’apertura di un file. Scopo della connect è “chiamare” un metodo in corrispondenza di un segnale generato dalla QAction; questo metodo lo chiameremo openFile e sarà responsabile di aprire il nostro file immagine che andremo a visualizzare.

Il distruttore:

MainWindow::~MainWindow(){

delete ui;}

Anche qui nulla di nuovo rispetto la lezione 2. Il distruttore si occupa di cancellare tutto ciò che era stato creato in precedenza.

Il metodo int MainWindow::openFile():

Per prima cosa analizziamo le seguenti righe di codice:

QList <QByteArray> supportedFilters;QString filters;QString defaultFilter;QImageReader reader;supportedFilters = reader.supportedImageFormats();

Si tratta delle dichiarazioni necessarie per permettere successivamente alla nostra applicazione di riconoscere quali sono i file immagine supportati (ad es PNG, JPG, BMP, etc...). Tutto si realizza attraverso la

Page 6: Qt Lezione3: un visualizzatore di immagini

Mini Guide Qt

Autore P. Sereno http://www.sereno-online.com/site

classe QImageReader che restituisce nella lista di ByteArray (cioè QList <QByteArray>) tutte le estensioni dei files immagine riconosciuti. In altre parole, con la linea di codice

supportedFilters = reader.supportedImageFormats();

Andiamo a riempire la lista “supportedfilters” con tutte quelle estensioni di file che il nostro sistema può leggere (cioè che le Qt sanno riconoscere grazie ai “decoder” di immagine installati).

Per approfondire questo argomento si può consultare la documentazione sul sito qtsoftware o il Qt Assistant.

A questo punto, consideriamo il codice seguente:

for (int i = 0; i < supportedFilters.size(); ++i) {

defaultFilter.append("*.");defaultFilter.append(supportedFilters[i].toUpper());defaultFilter.append(" ");filters.append(supportedFilters[i].toUpper());filters.append(" (*.");filters.append(supportedFilters[i]);filters.append(" );;");

}

si tratta di un ciclo for che itera sulla dimensione della lista “supportedfilters”. Questa lista infatti mette a disposizione un elevato numero di metodi, tutti molto utili, tra cui il metodo size() che ci informa sul numero di elementi contenuti nella lista.

Obiettivo del ciclo for è quello di creare una stringa (QString) contenente qualcosa del tipo: “*.PNG *.BMP *.JPG” e così via. Questa strana stringa ci servirà nel resto del codice per filtrare (da qui il nome filter…) quali files vogliamo andare ad aprire con la openFile.

Nota: le linee di codice di questo ciclo loop non devono essere considerate superficialmente, proviamo a cambiare qualcosa (ad esempio a rimuovere l’istruzione filters.append(" );;"); e osservate cosa succede.

Dopo il ciclo for concentriamoci ora su:

defaultFilter.append(");;");filters.append(tr("Any File( * )"));filters.prepend(defaultFilter);fileName=QFileDialog::getOpenFileName(this,tr("Open"),currentPath,filters);

le prime 3 linee di codice servono per preparare la stringa filters da passare come parametro a QFileDialog per selezionare solamente i files che ci interessa aprire (e cioè i files immagine supportati, ad esempio JPG, BMP, PNG etc.)

Fermiamoci ora su:

fileName=QFileDialog::getOpenFileName(this,tr("Open"),currentPath,filters);

questa linea di codice è molto importante! Essa infatti ci permette di far comparire la dialog box standard di apertura files illustrato in figura seguente:

Page 7: Qt Lezione3: un visualizzatore di immagini

Mini Guide Qt

Autore P. Sereno http://www.sereno-online.com/site

come si può osservare il campo Tipo File mostra l’indicazione

Images (*. BMP *.GIF *.ICO…

Questa è appunto la sequenza di filtri che abbiamo identificato grazie alle linee di codice che abbiamo visto precedentemente.

Vediamo ora i parametri passati alla QFileDialog::getOpenFileName

tr("Open")

è il titolo della dialog box. Non si è scelto di scrivere direttamente la stringa (è cioè “Open”) ma si è voluto passare attraverso il meccanismo della tr() per consentire la traduzione in lingue diverse dell’applicazione.

Può sembrare prematuro parlare subito di localizzazione, ma se ci abituiamo sin da subito a NON scrivere direttamente le nostre stringhe nel codice ma le mettiamo sempre dentro ad una tr(), ci toveremo poi pronti ad eseguire Qt Linguist (con lrelease/lupdate) per tradurre la nostra interfaccia utente. Per ora non ci addentriamo nei dettagli della localizzazione, ma ricordiamoci di scrivere tutte le nostre stringhe dentro ad

una tr(). SEMPRE!

currentPath

questo parametro serve ad indicare quale path usare alla getOpenFileName per visualizzare i files.

Per questo esempio currentPath è stato dichiarato ma non usato. Lascio al lettore il compito di

inizializzarlo.

filters

è la nostra lista di filtri per la selezione del tipo di file da aprire

Page 8: Qt Lezione3: un visualizzatore di immagini

Mini Guide Qt

Autore P. Sereno http://www.sereno-online.com/site

Arriviamo ora all’ultimo blocco di istruzioni:

if (!fileName.isEmpty()) // if fileName is not empty{

child = new QLabel(0);child->setPixmap(fileName);ui->mdiArea->addSubWindow(child);child->show();

}

quando viene selezionato un file, la getOpenFileName restituisce in fileName una stringa (vuota nel caso di nessun file selezionato).

L’istruzione:

if (!fileName.isEmpty())

serve appunto a verificare se un file è stato selezionato ed in tal caso si procede con il resto del codice, altrimenti il metodo openFile termina senza caricare alcun file.

isEmpty() è uno dei tanti metodi della classe QString (i metodi sono molti e tutti utilissimi!) e serve per sapere se la stringa è vuota.

Nel caso sia stato selezionato un file immagine verrà eseguito il codice seguente:

child = new QLabel(0);child->setPixmap(fileName);ui->mdiArea->addSubWindow(child);child->show();

e qui dobbiamo soffermarci un po’ per capire.

child è una istanza di QLabel, classe molto utile per visualizzare qualsiasi cosa: da una semplice stringa ad un’ immagine (che è proprio il nostro caso!)

La classe QLabel può visualizzare le immagini Pixmap; infatti il metodo setPixmap() ci consente proprio di caricare un’immagine il cui “fileName” (cioè il path) è il parametro passato come argomento (child->setPixmap(fileName);).A questo punto dobbiamo indicare alla mdiArea che c’è una nuova subwindow da visualizzare e questro viene fatto tramite la

ui->mdiArea->addSubWindow(child);

e per ultimo chiamiamo il metodo show() della QLabel ( child->show() ) per visualizzare la finestra child ed il gioco è fatto.

Page 9: Qt Lezione3: un visualizzatore di immagini

Mini Guide Qt

Autore P. Sereno http://www.sereno-online.com/site

Considerazioni finali

Questa è la terza lezione di un ciclo che verrà reso disponibile gratuitamente in Internet sul sito

http://www.sereno-online.com/site

A partire da questa lezione le cose si fanno più complicate, servirà quindi più tempo per capirle e per fare sul codice diverse prove.

Ogni vostro commento o richiesta di informazioni rappresenta un utile punto di partenza per nuove lezioni o miglioramenti.

Buon divertimento!

Paolo