I want to populate a combobox from SQLite, i took the example from https://felgo.com/doc/qt/qml-qtquick-controls2-combobox/ and https://felgo.com/doc/felgo-appdemos-showcase-qml-controls-customcombobox-qml/ and combined them into one, and have no clue as to how to populate the text control:
The Code
import Felgo 3.0
import QtQuick 2.5
import QtQuick.Controls 2.0 as Quick2
Quick2.ComboBox {
id: comboBox
implicitWidth: dp(90) + 20
implicitHeight: dp(24) + topPadding + bottomPadding
padding: dp(12)
editable: true
model: ListModel {
id: model
}
onAccepted: {
if (find(editText) === -1)
model.append({text: editText})
}
// overwrite style for density independent sizes
delegate: Quick2.ItemDelegate {
width: comboBox.implicitWidth
height: comboBox.implicitHeight
padding: dp(12)
contentItem: AppText {
text: modelData
color: highlighted ? Theme.tintColor : Theme.textColor
wrapMode: Text.NoWrap
}
highlighted: comboBox.highlightedIndex == index
}
contentItem: AppText {
leftPadding: 4
text: comboBox.displayText
width: comboBox.width - comboBox.indicator.width - comboBox.spacing
wrapMode: Text.NoWrap
}
}
The Database.js:
function dbInit()
{
// Create the database if it doesn't already exist
var db = LocalStorage.openDatabaseSync("MyDatabase", "1.0", "MyDatabase", 1000000);
try {
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS test ([rowid] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,Name TEXT,Description TEXT)');
})
} catch (err) {
console.log("Error creating table in database: " + err);
};
}
function dbGetHandle()
{
try {
var db = LocalStorage.openDatabaseSync("MyDatabase", "1.0", "MyDatabase", 1000000)
} catch (err) {
console.log("Error opening database: " + err)
}
return db
}
function dbInsert(Name,Description)
{
var db = dbGetHandle()
var rowid = 0;
db.transaction(function (tx) {
tx.executeSql('INSERT INTO test (Name,Description) VALUES(?, ?)',
[Name,Description])
var result = tx.executeSql('SELECT last_insert_rowid()')
rowid = result.insertId
})
return rowid;
}
function dbReadAll()
{
var db = dbGetHandle()
db.transaction(function (tx) {
var results = tx.executeSql(
'SELECT rowid,Name,Description FROM test order by rowid desc')
for (var i = 0; i < results.rows.length; i++) {
console.debug("id=" + results.rows.item(i).rowid + " Name: " + results.rows.item(i).Name)
comboBoxDbQueries.model.append({
id: results.rows.item(i).rowid,
Name: results.rows.item(i).Name,
Description: results.rows.item(i).Description
})
} // end for
})
}
This is the part I am having issues with:
contentItem: AppText {
text: modelData
without passing in a model modelData is undefined, if I pass it model, which is the id for the LIstModel, I get the error:
Unable to assign QQmlDMAbstractItemModelData to QString
I would have though it was model.data(index, role) not sure what role is, passing it 0 does not work, nor does model.get(index)
text: model.get(index).attributes.get(1).value
I get this error:
TypeError: Property ‘get’ of object QQmlDMAbstractItemModelData(0x55555677d1c0) is not a function
I was thinking that I want Name=1, Description=2, and ID is 0, but I can not even use the get function; seems like this is model.get(index).Name, does not work either.
This totally confuses me since I can
comboBoxDbQueries.model.append({
use the the append function, I did check the database and 3 records are there, and I can see 3 blanks in the drop down, just no text.
If there is a better way of doing this that works, please let me know, I have used this CustomComboBox, with list with no problem, but I have no idea how to append data to it in javascript without adding a ListModel.
I thought about adding:
could not figure out how to assign it to the comboBox as a model.
ListModel {
id: listModel
Component.onCompleted: {
Db.dbInit();
Db.dbReadAll()
comboBoxDbQueries.model = listModel;
}
}
I get the error:
ReferenceError: modelData is not defined in the CustomComboBox, and I have no idea where that reference comes from, I know its past as a <i>modelData</i> role, yet I can not assign the model this way, I also tried:
CustomComboBox {
id: comboBoxDbQueries
model: listModel
}
I know the answer is simple, I just do not see it.
Update: I did figure out why the drop down was not populating, if I changed modelData to Name it works, a hack, but the display does not work with: comboBox.displayText, its blank, how do I fix that, it does not get updated?
Project zipped
http://trinaryuniversity.org/temp/ComboBox.zip
A Hack works:
CustomComboBox {
id: comboBoxDbQueries
implicitWidth: dp(242) + 30
onCurrentIndexChanged: {
comboBoxDbQueries.displayText = listModel.get(comboBoxDbQueries.currentIndex).Name;
}
}
Getting closer; this is a version I used an onCurrentIndexChanged to update the displayText
Does anyone have any idea how to get this to work, this is the key to making this not a hack, I need the runtime value for element 0=id or 1=Name, I guess, it crashes, so I have no clue, reflection is not working the way I think it should:
listModel.get(comboBoxDbQueries.currentIndex).attributes.get(1).value
I had to hard code the database column name, which is why I call it a hack, besides having to fix the current index, my guess is that I did not set this up correctly, so it’s a hack.
http://trinaryuniversity.org/temp/ComboBoxHack.zip
How can I do this the right way?
Thanks for any help, I am stuck.