QT tips
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" per 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 e veloce consultazione su vari argomenti.
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