QML Google Suggest

From Qt Wiki
Revision as of 13:02, 28 November 2016 by EdwardWelbourne (talk | contribs) (Sub-categorize)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.


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

}
}