pyqt5 自动完成 QLineEdit - Google 地方自动完成
pyqt5 autocomplete QLineEdit - Google places autocomplete
我正在尝试在 pyqt5 QLineEdit 中创建这样的东西(自动完成位置)。
有一个名为 QCompleter 的 class,我可以用它来建议内容,但它需要一个已经形成的列表,但是这个 google 地方 api 是一个基于建议的功能,我怎样才能将每次击键发送到 google api 并获得建议并加载到 Qtextedit 中,有没有更好的方法来做到这一点
对于这种情况,您可以创建一个使用 Place Autocomplete 发出请求的自定义模型,并将该模型设置为 QCompleter:
import json
from PyQt5 import QtCore, QtGui, QtWidgets, QtNetwork
API_KEY = "<API_KEY>"
class SuggestionPlaceModel(QtGui.QStandardItemModel):
finished = QtCore.pyqtSignal()
error = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(SuggestionPlaceModel, self).__init__(parent)
self._manager = QtNetwork.QNetworkAccessManager(self)
self._reply = None
@QtCore.pyqtSlot(str)
def search(self, text):
self.clear()
if self._reply is not None:
self._reply.abort()
if text:
r = self.create_request(text)
self._reply = self._manager.get(r)
self._reply.finished.connect(self.on_finished)
loop = QtCore.QEventLoop()
self.finished.connect(loop.quit)
loop.exec_()
def create_request(self, text):
url = QtCore.QUrl("https://maps.googleapis.com/maps/api/place/autocomplete/json")
query = QtCore.QUrlQuery()
query.addQueryItem("key", API_KEY)
query.addQueryItem("input", text)
query.addQueryItem("types", "geocode")
query.addQueryItem("language", "en")
url.setQuery(query)
request = QtNetwork.QNetworkRequest(url)
return request
@QtCore.pyqtSlot()
def on_finished(self):
reply = self.sender()
if reply.error() == QtNetwork.QNetworkReply.NoError:
data = json.loads(reply.readAll().data())
if data['status'] == 'OK':
for prediction in data['predictions']:
self.appendRow(QtGui.QStandardItem(prediction['description']))
self.error.emit(data['status'])
self.finished.emit()
reply.deleteLater()
self._reply = None
class Completer(QtWidgets.QCompleter):
def splitPath(self, path):
self.model().search(path)
return super(Completer, self).splitPath(path)
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self._model = SuggestionPlaceModel(self)
completer = Completer(self, caseSensitivity=QtCore.Qt.CaseInsensitive)
completer.setModel(self._model)
lineedit = QtWidgets.QLineEdit()
lineedit.setCompleter(completer)
label = QtWidgets.QLabel()
self._model.error.connect(label.setText)
lay = QtWidgets.QFormLayout(self)
lay.addRow("Location: ", lineedit)
lay.addRow("Error: ", label)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.resize(400, w.sizeHint().height())
w.show()
sys.exit(app.exec_())
我遇到了同样的问题,起初我尝试了@eyllanasec 的回答。但出于某种原因,在我使用的平台(我正在使用 PyQt 为 Qt-based 软件创建插件)中,性能不是很好(经常卡住或挂起)。不过,它 运行 可以独立使用,所以可能是我的平台特有的。
最后找了一个类似案例的Qt示例工程,Google建议。你可以找到它 https://doc.qt.io/qt-5/qtnetwork-googlesuggest-example.html。它创建一个自定义 class 来处理搜索和 pop-up window(使用 QTreeWidget)。
由于示例是在 Qt 中,我将其移植到 PyQt 稍加修改https://github.com/ismailsunni/scripts/blob/master/autocomplete_from_url.py
我正在尝试在 pyqt5 QLineEdit 中创建这样的东西(自动完成位置)。
有一个名为 QCompleter 的 class,我可以用它来建议内容,但它需要一个已经形成的列表,但是这个 google 地方 api 是一个基于建议的功能,我怎样才能将每次击键发送到 google api 并获得建议并加载到 Qtextedit 中,有没有更好的方法来做到这一点
对于这种情况,您可以创建一个使用 Place Autocomplete 发出请求的自定义模型,并将该模型设置为 QCompleter:
import json
from PyQt5 import QtCore, QtGui, QtWidgets, QtNetwork
API_KEY = "<API_KEY>"
class SuggestionPlaceModel(QtGui.QStandardItemModel):
finished = QtCore.pyqtSignal()
error = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(SuggestionPlaceModel, self).__init__(parent)
self._manager = QtNetwork.QNetworkAccessManager(self)
self._reply = None
@QtCore.pyqtSlot(str)
def search(self, text):
self.clear()
if self._reply is not None:
self._reply.abort()
if text:
r = self.create_request(text)
self._reply = self._manager.get(r)
self._reply.finished.connect(self.on_finished)
loop = QtCore.QEventLoop()
self.finished.connect(loop.quit)
loop.exec_()
def create_request(self, text):
url = QtCore.QUrl("https://maps.googleapis.com/maps/api/place/autocomplete/json")
query = QtCore.QUrlQuery()
query.addQueryItem("key", API_KEY)
query.addQueryItem("input", text)
query.addQueryItem("types", "geocode")
query.addQueryItem("language", "en")
url.setQuery(query)
request = QtNetwork.QNetworkRequest(url)
return request
@QtCore.pyqtSlot()
def on_finished(self):
reply = self.sender()
if reply.error() == QtNetwork.QNetworkReply.NoError:
data = json.loads(reply.readAll().data())
if data['status'] == 'OK':
for prediction in data['predictions']:
self.appendRow(QtGui.QStandardItem(prediction['description']))
self.error.emit(data['status'])
self.finished.emit()
reply.deleteLater()
self._reply = None
class Completer(QtWidgets.QCompleter):
def splitPath(self, path):
self.model().search(path)
return super(Completer, self).splitPath(path)
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self._model = SuggestionPlaceModel(self)
completer = Completer(self, caseSensitivity=QtCore.Qt.CaseInsensitive)
completer.setModel(self._model)
lineedit = QtWidgets.QLineEdit()
lineedit.setCompleter(completer)
label = QtWidgets.QLabel()
self._model.error.connect(label.setText)
lay = QtWidgets.QFormLayout(self)
lay.addRow("Location: ", lineedit)
lay.addRow("Error: ", label)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.resize(400, w.sizeHint().height())
w.show()
sys.exit(app.exec_())
我遇到了同样的问题,起初我尝试了@eyllanasec 的回答。但出于某种原因,在我使用的平台(我正在使用 PyQt 为 Qt-based 软件创建插件)中,性能不是很好(经常卡住或挂起)。不过,它 运行 可以独立使用,所以可能是我的平台特有的。
最后找了一个类似案例的Qt示例工程,Google建议。你可以找到它 https://doc.qt.io/qt-5/qtnetwork-googlesuggest-example.html。它创建一个自定义 class 来处理搜索和 pop-up window(使用 QTreeWidget)。
由于示例是在 Qt 中,我将其移植到 PyQt 稍加修改https://github.com/ismailsunni/scripts/blob/master/autocomplete_from_url.py