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 !
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.
La mia "filosofia" (scusate la parola grossa !) e' utilizzare le cose per quello a cui sono 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()));
}
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.
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);
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()));
}
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.
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);
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;
} }
}
http://doc.trolltech.com/4.2/index.html
Autore: Antonio67
Data: Mon May 12 2008