QML Google Suggest

From Qt Wiki
Jump to: navigation, search


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:

gssnapshot.png

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

} }