QML Google Suggest
Jump to navigation
Jump to search
Google Suggest
This snippet article shows how to make a Google Suggest component to be used in conjunction with a TextInput element.
This is what it looks like:
Implementation
// GoogleSuggest.qml
import QtQuick 1.1
Rectangle {
id: googleSuggest
property string textToSugget
property string dsParam
property bool timeToDie: false
property int rowHeight: 30
width: parent.width
height: rowHeight*listView.count
anchors.top: parent.bottom
anchors.left: parent.left
anchors.topMargin: 5
signal itemChoosen(string suggestion);
onTimeToDieChanged: googleSuggest.destroy();
XmlListModel {
id: xmlModel
source: "http://suggestqueries.google.com/complete/search?output=toolbar"+
(dsParam!=="" ? "&ds="''dsParam : "")''
"&q="+textToSugget
query: "/toplevel/CompleteSuggestion"
XmlRole { name: "suggestion"; query: "suggestion/@data/string()" }
XmlRole { name: "num_queries"; query: "num_queries/@int/string()" }
}
ListView {
id: listView
anchors.fill: parent
cacheBuffer: 10
highlight: Rectangle { color: Qt.rgba(0,0,1,0.3); radius: 8; z: listView.z+10 }
highlightFollowsCurrentItem: true
interactive: false
currentIndex: -1
model: xmlModel
delegate: Rectangle {
id: resultRow
width: parent.width
height: rowHeight
color: (index % 2 === 0 ? "#ffffff" : "#eeeeff")
border.color: "#000000"
border.width: 1
radius: 8
Text {
id: result
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 5
anchors.right: numberOfResults.left
anchors.rightMargin: 10
font.pixelSize: 15
font.bold: true
text: suggestion
clip: true
}
Text {
id: numberOfResults
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 5
font.pixelSize: 12
font.italic: true
text: num_queries
}
}
MouseArea {
anchors.fill: listView
onMouseYChanged: {
listView.currentIndex = Math.floor((mouseY+rowHeight) / rowHeight)- 1;
}
onReleased: {
googleSuggest.itemChoosen(xmlModel.get(listView.currentIndex).suggestion);
timeToDie = true;
}
}
}
}
The functions below are used to dynamically load and unload the component. For example to pop up it when the user has entered at last 3 chars or unload it when TextInput.onAccepted signal is rised
// gs.js
var componentGS;
var objectGS;
// dsParam = "yt" only for YouTube suggest else it is empty
function popupGoogleSuggest ( callerItem, textString, dsParam ) {
deleteGoogleSuggest();
componentGS = Qt.createComponent("GoogleSuggest.qml");
objectGS = componentGS.createObject(callerItem);
if (objectGS === null) {
console.log("Error creating GoogleSuggest.qml", componentGS.errorString());
} else {
objectGS.textToSugget = textString;
objectGS.dsParam = dsParam;
}
return objectGS;
}
function deleteGoogleSuggest()
{
if (componentGS[[Image:==null && objectGS|==null && objectGS]]==undefined) {
objectGS.timeToDie = true;
}
}
Usage
import QtQuick 1.1
import "gs.js" as Functions
Rectangle {
id: main
width: 360
height: 360
Rectangle {
id: textContainer
x: 0; y:0; width: 250; height: 30
color: "#ffffff"
border.color: "#000000"
border.width: 1
TextInput {
id: textInput
property GoogleSuggest gsComponent
anchors.centerIn: parent
selectByMouse: true
text: "write here"
// Used to prevent predictive text to pop up while typing in a TextInput
// component. Else onTextChanged event isn't rised:
// https://bugreports.qt.nokia.com/browse/QTBUG-22298
inputMethodHints: Qt.ImhNoPredictiveText
function googleSuggest_item_choosen(text)
{
textInput.text=text;
}
Timer {
id: timerPopupGS
running: false
interval: 300
repeat: false
triggeredOnStart: false
onTriggered: {
if (textInput.focus && textInput.text !== "" && textInput.text.length > 2) {
// Pop up GoogleSuggest and catch itemChoosen signal
textInput.gsComponent = Functions.popupGoogleSuggest(textContainer, textInput.text, "");
textInput.gsComponent.itemChoosen.connect(textInput.googleSuggest_item_choosen);
}
if (textInput.text.length<3) Functions.deleteGoogleSuggest();
}
}
onTextChanged: {
timerPopupGS.restart();
if (text.length<3) Functions.deleteGoogleSuggest();
}
onAccepted: {
// eventually close VK
closeSoftwareInputPanel();
Functions.deleteGoogleSuggest();
}
onFocusChanged: {
if (!focus) closeSoftwareInputPanel();
if (!textInput.focus) {
Functions.deleteGoogleSuggest();
}
}
}
}
}