Example of a model for use with QtQuick ComboBox (qml)
-
Does anyone have an example of a pyside2 model for use with a QComboBox? It seems that no matter what I throw at it, it either doesn't render the text properly, or doesn't accept the model.
I've attempted modified models with both QStandardItemModel and QAbstractItemModel. I only need to load the ComboBox with a list of strings.
Is there documentation or a way that I reveals the default model?
-
Solved this... turns out I was trying to hard...
A python list will automatically be converted to a QStringList for qml. To update the model, just call engine.rootContext().setContextProperty() again as the combobox doesn't know when the string list changes.
.py code
comportComboModel = ['1','2','3','4','5'] engine.rootContext().setContextProperty("comModel", comportComboModel)
.qml code
ComboBox { id: comComboBox width: 100 font.pointSize: 12 rightPadding: 0 currentIndex: 0 flat: true model: comModel }
-
Hi and welcome to devnet,
Since it's just a list of strings, why not use QComboBox.addItems ?
-
@SGaist Honestly, I'm not 100% how to. I can modify buttons and text just fine, but every time I try to clear/addItems/etc to this ComboBox it ignores it. Signal/Slots between qml and python is very convoluted at times. The combobox needs to be continuously updated, so it would be cleaner and easier to manage with model. I think addItems() and clear() aren't working because i'm initializing the model in qml?
I'm trying to figure out how to format QStandardItemModel properly so it accepts it.
Here is some example test code. The function prints the log entry 'adding 4!' but does not add the item to the list. I've tried other commands and also "Connections" with the signal, etc. I can't seem to edit the ComboBox model in anyway.
.py class Backend(QObject): addToModel = Signal() def __init__(self): QObject.__init__(self) QTimer.singleShot(1000, self.add) def add(self): self.addToModel.emit() ... app = QGuiApplication(sys.argv) engine = QQmlApplicationEngine() backend = Backend() # link engine to logic, load single qml file engine.rootContext().setContextProperty("backend", backend) engine.load(os.path.join(os.path.dirname(__file__), "main.qml")) ...
.qml ComboBox { id: comportComboBox width: 100 font.pointSize: 12 rightPadding: 0 currentIndex: 0 flat: true model: ['1','2','3'] Component.onCompleted: backend.addToModel.connect(addToModel) function addToModel() { backend.log('adding 4!') comportComboBox.additems(["4"]) } }
-
Update to the situation, QComboBox is accepting a QStandardItemModel now, but doesn't display text (it only displays 10 empty boxes). It the default model storing draw data somehow?
.py code
class ComboBoxModel(QStandardItemModel): def __init__(self): QStandardItemModel.__init__(self) for x in range(10): item = QStandardItem(str(x)) item.setCheckable(True) self.appendRow(item) self.comComboModel = ComboBoxModel() engine.rootContext().setContextProperty("comComboModel", leash.comportComboModel)
.qml code
ComboBox { id: comComboBox width: 100 font.pointSize: 12 rightPadding: 0 currentIndex: 0 flat: true model: comportComboModel }
The problem is it displays this...
-
Sorry I missed the part about QML. QComboBox is part of the Qt widgets module and it's not the same a a QtQuick ComboBox.
As for using custom models, did you already took a look at the C++ version of the QtQuick Model Views Data chapter of Qt's documentation ? That should give you the basic knowledge to create custom models. You'll have to translate that to Python though.
-
@SGaist thanks, I don't really follow that documentation. I tried to create a QStringListModel in python and passed it to QtQuick ComboBox. It does the same thing as before, it renders the combobox list and has the correct number of items (I can hover and see them light up) but the text still doesn't display. I assume QtQuick ComboBox either isn't converting the strings properly, or I'm not storing the strings properly?
.py code
class ComboBoxModel2(QStringListModel): def __init__(self): QStringListModel.__init__(self) self.setStringList(['1','2','3','4']) self.comComboModel2 = ComboBoxModel2() engine.rootContext().setContextProperty("comComboModel2", leash.comportComboModel2)
.qml code
ComboBox { id: comComboBox width: 100 font.pointSize: 12 rightPadding: 0 currentIndex: 0 flat: true model: comComboModel2 }
Once again this displays the 4 buttons, but they do not contain text. Frustrating to say the least... python and qml do not play nice.
-
Solved this... turns out I was trying to hard...
A python list will automatically be converted to a QStringList for qml. To update the model, just call engine.rootContext().setContextProperty() again as the combobox doesn't know when the string list changes.
.py code
comportComboModel = ['1','2','3','4','5'] engine.rootContext().setContextProperty("comModel", comportComboModel)
.qml code
ComboBox { id: comComboBox width: 100 font.pointSize: 12 rightPadding: 0 currentIndex: 0 flat: true model: comModel }