aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorjaime02 <gemailpersonal02@gmail.com>2022-02-15 12:10:46 +0100
committerCristián Maureira-Fredes <cristian.maureira-fredes@qt.io>2022-06-02 06:43:22 +0200
commit0a187a3aa58d326349d6c3415a031f0f68fdb84a (patch)
tree8ee9ccf697563b53082e7eab7d1d53c742538888 /examples
parentdc06e881f72f2added3b7211a78e2ec15065a623 (diff)
example: add google suggest
Ported from C++ Task-number: PYSIDE-841 Pick-to: 6.2 6.3 Change-Id: Ib64218925961f3d0bbd783c5bb9d8365a81e8767 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'examples')
-rw-r--r--examples/network/googlesuggest/doc/googlesuggest.pngbin0 -> 2467 bytes
-rw-r--r--examples/network/googlesuggest/doc/googlesuggest.rst11
-rw-r--r--examples/network/googlesuggest/googlesuggest.py137
-rw-r--r--examples/network/googlesuggest/googlesuggest.pyproject3
-rw-r--r--examples/network/googlesuggest/main.py14
-rw-r--r--examples/network/googlesuggest/searchbox.py27
6 files changed, 192 insertions, 0 deletions
diff --git a/examples/network/googlesuggest/doc/googlesuggest.png b/examples/network/googlesuggest/doc/googlesuggest.png
new file mode 100644
index 000000000..cb2e91d4d
--- /dev/null
+++ b/examples/network/googlesuggest/doc/googlesuggest.png
Binary files differ
diff --git a/examples/network/googlesuggest/doc/googlesuggest.rst b/examples/network/googlesuggest/doc/googlesuggest.rst
new file mode 100644
index 000000000..ada224311
--- /dev/null
+++ b/examples/network/googlesuggest/doc/googlesuggest.rst
@@ -0,0 +1,11 @@
+Google Suggest Example
+======================
+
+Obtains the list of search recommendations by the Google search engine.
+
+The example uses the QNetworkAccessManager to obtain the list of search
+recommendations by Google as the user types into a QLineEdit.
+
+.. image:: googlesuggest.png
+ :width: 502
+ :alt: google suggest program screenshot
diff --git a/examples/network/googlesuggest/googlesuggest.py b/examples/network/googlesuggest/googlesuggest.py
new file mode 100644
index 000000000..6dac0eb22
--- /dev/null
+++ b/examples/network/googlesuggest/googlesuggest.py
@@ -0,0 +1,137 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from typing import List
+
+from PySide6.QtCore import (QByteArray, QEvent, QObject, QPoint, Qt, QTimer,
+ QXmlStreamReader, Slot)
+from PySide6.QtGui import QPalette
+from PySide6.QtNetwork import (QNetworkAccessManager, QNetworkReply,
+ QNetworkRequest)
+from PySide6.QtWidgets import QFrame, QTreeWidget, QTreeWidgetItem
+
+
+class GSuggestCompletion(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.editor = parent
+ self.popup = QTreeWidget()
+ self.popup.setWindowFlags(Qt.Popup)
+ self.popup.setFocusPolicy(Qt.NoFocus)
+ self.popup.setFocusProxy(parent)
+ self.popup.setMouseTracking(True)
+
+ self.popup.setColumnCount(1)
+ self.popup.setUniformRowHeights(True)
+ self.popup.setRootIsDecorated(False)
+ self.popup.setEditTriggers(QTreeWidget.NoEditTriggers)
+ self.popup.setSelectionBehavior(QTreeWidget.SelectRows)
+ self.popup.setFrameStyle(QFrame.Box | QFrame.Plain)
+ self.popup.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
+ self.popup.header().hide()
+
+ self.popup.installEventFilter(self)
+
+ self.popup.itemClicked.connect(self.done_completion)
+
+ self.timer = QTimer()
+ self.timer.setSingleShot(True)
+ self.timer.setInterval(500)
+ self.timer.timeout.connect(self.auto_suggest)
+ self.editor.textEdited.connect(self.timer.start)
+
+ self.network_manager = QNetworkAccessManager()
+ self.network_manager.finished.connect(self.handle_network_data)
+
+ def eventFilter(self, obj: QObject, ev: QEvent):
+ if obj is not self.popup:
+ return False
+ if ev.type() == QEvent.MouseButtonPress:
+ self.popup.hide()
+ self.editor.setFocus()
+ return True
+
+ if ev.type() == QEvent.KeyPress:
+ consumed = False
+ key = ev.key()
+ if key in (Qt.Key_Enter, Qt.Key_Return):
+ self.done_completion()
+ consumed = True
+ elif key == Qt.Key_Escape:
+ self.editor.setFocus()
+ self.popup.hide()
+ consumed = True
+ elif key in (
+ Qt.Key_Up,
+ Qt.Key_Down,
+ Qt.Key_Home,
+ Qt.Key_End,
+ Qt.Key_PageUp,
+ Qt.Key_PageDown,
+ ):
+ pass
+ else:
+ self.editor.setFocus()
+ self.editor.event(ev)
+ self.popup.hide()
+ return consumed
+ return False
+
+ def show_completion(self, choices: List[str]):
+ if not choices:
+ return
+ pal = self.editor.palette()
+ color = pal.color(QPalette.Disabled, QPalette.WindowText)
+
+ self.popup.setUpdatesEnabled(False)
+ self.popup.clear()
+
+ for choice in choices:
+ item = QTreeWidgetItem(self.popup)
+ item.setText(0, choice)
+ item.setForeground(0, color)
+
+ self.popup.setCurrentItem(self.popup.topLevelItem(0))
+ self.popup.resizeColumnToContents(0)
+ self.popup.setUpdatesEnabled(True)
+
+ self.popup.move(self.editor.mapToGlobal(QPoint(0, self.editor.height())))
+ self.popup.setFocus()
+ self.popup.show()
+
+ @Slot()
+ def done_completion(self):
+ self.timer.stop()
+ self.popup.hide()
+ self.editor.setFocus()
+ item = self.popup.currentItem()
+ if item:
+ self.editor.setText(item.text(0))
+ self.editor.returnPressed.emit()
+
+ @Slot()
+ def auto_suggest(self):
+ s = self.editor.text()
+ url = f"https://google.com/complete/search?output=toolbar&q={s}"
+ self.network_manager.get(QNetworkRequest(url))
+
+ def prevent_suggest(self):
+ self.timer.stop()
+
+ @Slot()
+ def handle_network_data(self, network_reply: QNetworkReply):
+ url = network_reply.url()
+ if network_reply.error() == QNetworkReply.NoError:
+ choices: List[str] = []
+
+ response: QByteArray = network_reply.readAll()
+ xml = QXmlStreamReader(response)
+ while not xml.atEnd():
+ xml.readNext()
+ if xml.tokenType() == QXmlStreamReader.StartElement:
+ if xml.name() == "suggestion":
+ s = xml.attributes().value("data")
+ choices.append(s)
+ self.show_completion(choices)
+
+ network_reply.deleteLater()
diff --git a/examples/network/googlesuggest/googlesuggest.pyproject b/examples/network/googlesuggest/googlesuggest.pyproject
new file mode 100644
index 000000000..a8cb57674
--- /dev/null
+++ b/examples/network/googlesuggest/googlesuggest.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["main.py", "googlesuggest.py"]
+}
diff --git a/examples/network/googlesuggest/main.py b/examples/network/googlesuggest/main.py
new file mode 100644
index 000000000..1efda08e6
--- /dev/null
+++ b/examples/network/googlesuggest/main.py
@@ -0,0 +1,14 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtWidgets import QApplication
+
+from searchbox import SearchBox
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ search_edit = SearchBox()
+ search_edit.show()
+ sys.exit(app.exec())
diff --git a/examples/network/googlesuggest/searchbox.py b/examples/network/googlesuggest/searchbox.py
new file mode 100644
index 000000000..9cbe20b23
--- /dev/null
+++ b/examples/network/googlesuggest/searchbox.py
@@ -0,0 +1,27 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import Slot
+from PySide6.QtGui import QDesktopServices
+from PySide6.QtWidgets import QLineEdit
+
+from googlesuggest import GSuggestCompletion
+
+
+class SearchBox(QLineEdit):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.completer = GSuggestCompletion(self)
+
+ self.returnPressed.connect(self.do_search)
+ self.setWindowTitle("Search with Google")
+
+ self.adjustSize()
+ self.resize(400, self.height())
+ self.setFocus()
+
+ @Slot()
+ def do_search(self):
+ self.completer.prevent_suggest()
+ url = f"https://www.google.com/search?q={self.text()}"
+ QDesktopServices.openUrl(url)