Creare una nuova classe: differenze tra le versioni
(→la GreeterApp ed altro ...) |
m (→link ad autoCompletion-v2) |
||
(Una versione intermedia di uno stesso utente non è mostrata) | |||
Riga 1: | Riga 1: | ||
− | [https://github.com/cloc3/sddm/tree/autoCompletion-v1 Attualmente], il codice della feature di autocompletamento è incluso all'interno della classe UserModel.<br> | + | [https://github.com/cloc3/sddm/tree/autoCompletion-v1 Attualmente], il codice della feature di autocompletamento è incluso all'interno della classe '''UserModel'''.<br> |
L'interazione tra questi elementi, tuttavia, è limitata a due sole funzioni: | L'interazione tra questi elementi, tuttavia, è limitata a due sole funzioni: | ||
# Passare gli username al codice di autocompletamento tramite la Qlist '''Users'''; | # Passare gli username al codice di autocompletamento tramite la Qlist '''Users'''; | ||
− | # Comunicare con il codice QML tramite le chiamate alle nuove proprietà | + | # Comunicare con il codice QML tramite le chiamate alle nuove proprietà ('''Q_PROPRIETY'''). |
Troppo poco per ammassare tanto codice in un'unica classe.<br> | Troppo poco per ammassare tanto codice in un'unica classe.<br> | ||
− | Anziché acquisire gli username dalla classe UserModel, è meglio ricaricarli direttamente attraverso una chiamata a getpwent.<br> | + | Proviamo perciò a riscrivere la patch, facendo riferimento al branch in [https://github.com/cloc3/sddm/tree/autoCompletion-v2 versione 2] del nostro fork. |
+ | |||
+ | Anziché acquisire gli username dalla classe UserModel, è meglio ricaricarli direttamente attraverso una chiamata a '''getpwent'''.<br> | ||
La comunicazione con il codice QML, invece, deve essere impostata nella classe GreeterApp, che inizializza l'intero programma.<br> | La comunicazione con il codice QML, invece, deve essere impostata nella classe GreeterApp, che inizializza l'intero programma.<br> | ||
Sono in tutto 5 righe di codice: | Sono in tutto 5 righe di codice: | ||
Riga 16: | Riga 18: | ||
GreeterApp.cpp: view->rootContext()->setContextProperty(QStringLiteral("autoCompletion"), m_autoCompletion); | GreeterApp.cpp: view->rootContext()->setContextProperty(QStringLiteral("autoCompletion"), m_autoCompletion); | ||
− | Interessante, in particolare, l'ultima riga. Fa in modo che il codice QML riconosca la chiave ''autoCompletion'' per acccedere alle proprietà specifiche della nuova classe | + | Interessante, in particolare, l'ultima riga. Fa in modo che il codice QML riconosca la chiave ''autoCompletion''' (con la ''a'' minuscola) per acccedere alle proprietà specifiche della nuova classe. |
Una classe deve contenere: | Una classe deve contenere: | ||
− | - Le | + | - Le Q_PROPERTY di interazione; |
- Un costruttore di inizializzazione; | - Un costruttore di inizializzazione; | ||
− | - Le | + | - Le proprie funzioni specifiche. |
− | Nel nostro caso le proprietà sono le stesse già descritte in [[QML|precedenza]]: '' | + | Nel nostro caso le proprietà sono le stesse già descritte in [[QML|precedenza]]: ''auC'',''head'' e ''tail''.<br> |
Il costruttore replica quello della classe Usermodel, ma ha un contenuto vuoto: | Il costruttore replica quello della classe Usermodel, ma ha un contenuto vuoto: | ||
AutoCompletion::AutoCompletion(QObject *parent) : QAbstractListModel(parent), d(new AutoCompletionPrivate()) {} | AutoCompletion::AutoCompletion(QObject *parent) : QAbstractListModel(parent), d(new AutoCompletionPrivate()) {} | ||
− | La sua funzione è quella di preparare un puntatore | + | La sua funzione è soltanto quella di preparare un puntatore alla classe ''AutoCompletion'' di tipo '''QAbstractListModel''', affinché (in futuro), l'autocompletamento si possa far carico di costruire dinamicamente la lista utenti, sostituendo l'implementazione statica della classe UserModel.<br> |
− | L'inizializzazione reale della classe AutoCompletion sarà invece delegata alla | + | L'inizializzazione reale della classe ''AutoCompletion'' sarà invece delegata alla funzione '''initAutoCompletion''' e sarà invocata esclusivamente ai layout che ne richiedono esplicitamente l'uso.<br> |
+ | Bisogna osservare che impostare una classe come QAbstractListModel impone l'introduzione di alcune funzioni obbligatorie: | ||
+ | - ''int AutoCompletion::rowCount(...)'' | ||
+ | - ''QVariant AutoCompletion::data()'' | ||
+ | - ''QHash<int, QByteArray> AutoCompletion::roleNames()'' (non obbligatoria, ma mantenuta per analogia) | ||
+ | Queste funzioni sono state implementate in analogia con la versione corrispondente di UserModel. | ||
+ | |||
+ | Riassumendo, la gestione della classe si articola in tre fasi distinte: | ||
+ | # Impostazione del dialogo con QML, gestito nella classe di apertura GreeterApp, tramite una chiamata al costruttore vuoto '''AutoCompletion(...); | ||
+ | # Inizializzazione della ricerca, su richiesta QML, tramite la proprieà '''autoCompletion.initAutoCompletion''', che carica i nomi utente con '''getpwent'''; | ||
+ | # Dialogo dinamico con il QML tramite le proprietà '''autoCompletion.head''' e '''autoCompletion.tail''', identiche alle verioni già descritte in precedenza. |
Versione attuale delle 21:27, 16 ago 2016
Attualmente, il codice della feature di autocompletamento è incluso all'interno della classe UserModel.
L'interazione tra questi elementi, tuttavia, è limitata a due sole funzioni:
- Passare gli username al codice di autocompletamento tramite la Qlist Users;
- Comunicare con il codice QML tramite le chiamate alle nuove proprietà (Q_PROPRIETY).
Troppo poco per ammassare tanto codice in un'unica classe.
Proviamo perciò a riscrivere la patch, facendo riferimento al branch in versione 2 del nostro fork.
Anziché acquisire gli username dalla classe UserModel, è meglio ricaricarli direttamente attraverso una chiamata a getpwent.
La comunicazione con il codice QML, invece, deve essere impostata nella classe GreeterApp, che inizializza l'intero programma.
Sono in tutto 5 righe di codice:
$ grep utoCompletion GreeterApp.h GreeterApp.cpp GreeterApp.h: class AutoCompletion; GreeterApp.h: AutoCompletion *m_autoCompletion { nullptr }; GreeterApp.cpp:#include "AutoCompletion.h" GreeterApp.cpp: m_autoCompletion = new AutoCompletion(); GreeterApp.cpp: view->rootContext()->setContextProperty(QStringLiteral("autoCompletion"), m_autoCompletion);
Interessante, in particolare, l'ultima riga. Fa in modo che il codice QML riconosca la chiave autoCompletion' (con la a minuscola) per acccedere alle proprietà specifiche della nuova classe.
Una classe deve contenere:
- Le Q_PROPERTY di interazione; - Un costruttore di inizializzazione; - Le proprie funzioni specifiche.
Nel nostro caso le proprietà sono le stesse già descritte in precedenza: auC,head e tail.
Il costruttore replica quello della classe Usermodel, ma ha un contenuto vuoto:
AutoCompletion::AutoCompletion(QObject *parent) : QAbstractListModel(parent), d(new AutoCompletionPrivate()) {}
La sua funzione è soltanto quella di preparare un puntatore alla classe AutoCompletion di tipo QAbstractListModel, affinché (in futuro), l'autocompletamento si possa far carico di costruire dinamicamente la lista utenti, sostituendo l'implementazione statica della classe UserModel.
L'inizializzazione reale della classe AutoCompletion sarà invece delegata alla funzione initAutoCompletion e sarà invocata esclusivamente ai layout che ne richiedono esplicitamente l'uso.
Bisogna osservare che impostare una classe come QAbstractListModel impone l'introduzione di alcune funzioni obbligatorie:
- int AutoCompletion::rowCount(...) - QVariant AutoCompletion::data() - QHash<int, QByteArray> AutoCompletion::roleNames() (non obbligatoria, ma mantenuta per analogia)
Queste funzioni sono state implementate in analogia con la versione corrispondente di UserModel.
Riassumendo, la gestione della classe si articola in tre fasi distinte:
- Impostazione del dialogo con QML, gestito nella classe di apertura GreeterApp, tramite una chiamata al costruttore vuoto AutoCompletion(...);
- Inizializzazione della ricerca, su richiesta QML, tramite la proprieà autoCompletion.initAutoCompletion, che carica i nomi utente con getpwent;
- Dialogo dinamico con il QML tramite le proprietà autoCompletion.head e autoCompletion.tail, identiche alle verioni già descritte in precedenza.