Repository 32bit  Forum
Repository 64bit  Wiki

QT tips

Da Slacky.eu.

Indice

Introduzione

Questa che riporto e' una pagina man scritta da me per tenere a "portata di mano" le cose che ritengo piu' utili durante lo sviluppo di applicazioni con Qt. Ovviamente ci sono metodi piu' "automatizzati" di fare certe cose, ma tendo sempre a fare le cose a mano, in modo da capire bene quello che succede.

Dopo 5/6 mesi, dover "rimettere mano" ad un codice fatto da me, piuttosto che scavare nel codice "generato" fa una bella differenza !

Conoscenze

Il breve documento prevede una conoscenza gia' acquisita dell'utilizzo di Qt. Questo vuol essere solo un promemoria di facile consultazione su alcuni argomenti utilizzabili con queste librerie.

Qt designer

La mia "filosofia" (scusate la parola grossa !) e' utilizzare le cose per quello a cui sono destinate destinate, soprattutto nell'ambito della programmazione. Il Qt designer, quindi, dovrebbe occuparsi del design dell'interfaccia utente ... e basta. L'utilizzo che ne faccio e' quindi limitato ad impostare le grid e i campi del form, ma al momento della programmazione passo decisamente a vi.

Ipotizziamo quindi di aver creato una interfaccia utente, e la classe l'abbiamo chiamato Start. Abbiamo poi salvato il tutto nel file MeinUindov.

Nel file MyWin.h della classe che utilizzera' la UI inseriamo la doppia inheritance:

#include <QtGui>
#include "ui_MeinUindov.h"

class MyWin : public QMainWindow, private Ui::Start
{
     Q_OBJECT
     public:
          MyWin(QWidget *parent=0);
     private slots:
          void unoSL();
          void dueSL();
};

E nel file MyWin.cpp avremo accesso alle actions create in Qt designer:

#include "MyWin.h"

MyWin::MyWin(QWidget *parent) : QMainWindow(parent)
{
     setupUi(this);

     /***************************
     connettiamo i pulsanti della
     UI con gli SLOT della classe
     ***************************/
     connect(actionQuit,SIGNAL(triggered()),this,SLOT(close()));
     connect(actionUno,SIGNAL(clicked()),this,SLOT(unoSL()));
}

Utilizzo di QSqlTableModel e QSqlRelationalTableModel.

Per associare una tabella del database ad un SQL model:

     QSqlTableModel *model;
     model = new QSqlTableModel();
     model->setTable("intesta");

Se la tabella contiene foreign keys, utilizzare:

     QSqlRelationalTableModel *model;
     model = new QSqlRelationalTableModel();
     model->setTable("intesta");
     model->setRelation(2, QSqlRelation("city", "id", "nome"));

L'ultima riga specifica che il field numero 2 della tabella intesta e' in relazione alla tabella city attraverso il campo id e che deve essere mostrato il campo nome nella view.

Mappare un SqlModel ad un widget form

Per mappare uno degli SqlModel creati ai campi di un form creato manualmente, utilizzare QDataWidgetMapper:

      QDataWidgetMapper *mapper;
      mapper = new QDataWidgetMapper();
      mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
      mapper->setModel(model);
      mapper->addMapping(leNome, 1);
      mapper->addMapping(leInd, 2);
      mapper->addMapping(lePiva, 3);

Utilizzo

Una volta creato il model e l'equivalente mapper, si interagisce con il form cosi':

       // TROVA

            QString filter = QString("nome ILIKE '%1%').arg(leNome->text());
            model->setFilter(filter);
            model->setSort(1, Qt::AscendingOrder);
            model->select();

            if (!model->rowCount()) {
                 QMessageBox::warning(this, tr("Find error"), tr("Not found"));
            } else {
                 mapper->toFirst();
            }

       // INSERISCI o VARIA

            if (mapper->currentIndex() == -1) {
                 // e' un inserimento quindi crea un nuovo record vuoto,
                 // lo inserisce alla fine del "model" e sposta
                 // il "mapper" all'ultimo record.
                 // newRec.field("...").setNull(); per settare il
                 // field a NULL.
                 //
                 QSqlRecord newRec = model->record();
                 newRec->setValue("nome", leNome->text());
                 newRec->setValue("ind", leInd->text());
                 newRec->setValue("cap", leCap->text());

                 model->insertRecord(-1, newRec);
                 mapper->toLast();
            }

            if (!mapper->submit()) {
                 QMessageBox::critical(this, tr("Errore salvataggio"),
                 tr("ERRORE DB: %1").arg(db.lastError().text()));
            }

Controllo dei fields per INSERT/UPDATE

Per controllare il formato dei fields, settare il "case" delle QString ed eventualmente settarli a NULL, connettere i SIGNALS beforeInsert(QSqlRecord &rec) e beforeUpdate(int row, QSqlRecord &rec) del QSqlTableModel a metodi della classe:

       connect(model, SIGNAL(beforeInsert(QSqlRecord &)),
              this, SLOT(insertRecord(QSqlRecord &)));
       connect(model, SIGNAL(beforeUpdate(int, QSqlRecord &)),
              this, SLOT(updateRecord(int, QSqlRecord &)));

Da questi metodi si puo' accedere ai fields del record ed effettuare le variazioni e i controlli eventuali. Esiste anche il SIGNAL beforeDelete(QSqlRecord &rec), per gestire eventualmente foreign keys o cose del genere.

Style delle QLabel di una widget

Per uniformare lo style delle QLabel di una widget, usare il metodo findChildren() di QObject:

     setLayout(grid);
     QList<QLabel *> lb_list = this->findChildren<QLabel *>();

     for (int conta=0; conta<lb_list.size(); conta++) {
               lb_list.at(conta)->setFrameStyle(QFrame::Box|QFrame::Sunken);
               lb_list.at(conta)->setAlignment(
                   Qt::AlignCenter | Qt::AlignRight);

key press event

Per utilizzare la keyboard in una widget, per prima cosa dichiarare nell'header file il metodo protected:

          class Klasse : public QWidget
          {
               Q_OBJECT
              public:
                   Klasse(QWidget *parent=0);
              protected:
                   void keyPressEvent(QKeyEvent *event);
          }

Poi nel file cpp intercettare i key e ignorare quelli che non servono. Nell'esempio successivo e' stato utilizzato un QDataWidgetMapper e lo spostamento tra i record viene fatto con PageUp e PageDown:

          void Dest::keyPressEvent(QKeyEvent *event)
          {
                   // per andare avanti ed indietro nei record
                   // trovati nella ricerca.
                   //
                   switch (event->key()) {
                        case Qt::Key_PageUp:
                             if (mapper->currentIndex() == -1) {
                                  QMessageBox::information(this,
                                       "Informazione",
                                       "Nessuna ricerca in corso");
                             }

                             mapper->toPrevious();
                             break;
                        case Qt::Key_PageDown:
                             if (mapper->currentIndex() == -1) {
                                  QMessageBox::information(this,
                                       "Informazione",
                                       "Nessuna ricerca in corso");
                             }

                             mapper->toNext();
                             break;
                        default:
                             event->ignore();
                             break;
                   }            }
          }

Links

http://doc.trolltech.com/4.2/index.html


Autore: Antonio67

Data: Mon May 12 2008

Strumenti personali
Namespace

Varianti