2015-02-14 16 views
5

Sto scrivendo un piccolo programma che utilizza Qt5 QML come livello GUI e Python3-PyQt5 per implementare il modello dati.Voglio impostare un Qt QML Combobox su una proprietà dell'oggetto PyQt5

Ora desidero visualizzare uno ComboBox in QML e impostare il modello su un elenco di enumerazioni. Come esporterei l'enum come una proprietà della classe python in modo che io possa fare riferimento in QML?

Preferibilmente vorrei scrivere questo in QML:

ComboBox { 
    model: mymodel.car_manufacturers 
    onCurrentIndexChanged: mymodel.selected_manufacturer = currentIndex 
} 

risposta

2

Qui è la mia soluzione che funziona abbastanza bene per me. Nel codice python ho il seguente:

class CarManufacturers(enum.Enum): 
    BMW, Mercedes = range(2) 

mfcChanged = pyqtSignal() 

@pyqtProperty('QStringList', constant=True) 
def carmanufacturers(self): 
    return [mfc.name for mfc in CarManufacturers] 

@pyqtProperty('QString', notify=mfcChanged) 
def mfc(self): 
    return str(CarManufacturers[self._mfc].value) 

@modus.setter 
def mfc(self, mfc): 
    print('mfc changed to %s' % mfc) 
    if self._mfc != CarManufacturers(int(mfc)).name: 
     self._mfc = CarManufacturers(int(mfc)).name 
     self.mfcChanged.emit() 

e in QML ho:

ComboBox { 
    model: myModel.carmanufacturers 
    currentIndex: myModel.mfc 
    onCurrentIndexChanged: myModel.mfc = currentIndex 
} 
0

Si dovrebbe mettere l'enum nella classe che deriva da QObject. Inoltre dovrebbe essere contrassegnato con la macro Q_ENUMS. Puoi quindi prendere lo QMetaEnum del tuo enum dal metaoggetto della classe, scorrere tra le chiavi e i relativi valori e aggiungerne uno a uno QStringList.

in C++ sarebbe come:

MyClass myObj; 
const QMetaObject* metaObj = myObj.metaObject(); 
QMetaEnum enumType = metaObj->enumerator(metaObj->indexOfEnumerator("MyEnumType")); 

QStringList list; 
for(int i=0; i < enumType.keyCount(); ++i) 
{ 
    QString item = QString::fromLatin1(enumType.key(i)) + " " 
       + QString::number(enumType.value(i)); 
    list.append(item); 
} 

Ora è possibile utilizzare QQmlContext::setContextProperty per esporre la lista la stringa da QML:

QQmlContext *context = engine.rootContext(); 
context->setContextProperty("myModel", QVariant::fromValue(list)); 

Si avrebbe una combo-box contenente la chiave enum e valori quando l'articolo ComboBox è:

ComboBox { 
    model: myModel 
    ... 
} 
+0

Grazie per il vostro sforzo, ma io che ho bisogno suggerimenti PyQt più diretti. Per una volta non c'è più un tipo QStringList. E il mio secondo problema è che ho solo un modello principale registrato che viene quindi istanziato da un file QML che viene estratto da un programma di caricamento. Quindi non riesco più a raggiungere il motore qml in runtime, penso. Può essere fatto senza la chiamata setContextProperty? – Fabian