I want to set a Qt QML Combobox to a PyQt5 object property

怎甘沉沦 提交于 2020-01-14 09:32:08

问题


I am writing a small program which uses Qt5 QML as the GUI layer and Python3-PyQt5 to implement the data model.

I now want to display a ComboBox in QML and set its model to a list of enums. How would I export the enum as a property of the python class so that I can reference it in QML?

Preferably I would write this in QML:

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

回答1:


Here is my solution which works good enough for me. In the python code I have the following:

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()

and in the QML I have:

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



回答2:


You should put the enum in your class that derives from QObject. Also it should be marked with Q_ENUMS macro. You can then take the QMetaEnum of your enum from the metaobject of the class, iterate through the keys and their values and add each one to a QStringList.

In C++ it would be like :

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);
}

Now you can use QQmlContext::setContextProperty to expose the the string list to QML :

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

You would have a combo-box containing the enum key and values when the ComboBox item is like :

ComboBox {
  model: myModel
  ...
}


来源:https://stackoverflow.com/questions/28517132/i-want-to-set-a-qt-qml-combobox-to-a-pyqt5-object-property

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!