我正在尝试在 pyqt5 QLineEdit 中创建类似这样的内容(自动完成位置)。
有一个名为 QCompleter 的类,我可以用它来建议内容,但它需要一个已经形成的列表,但是这个 google places api 是一个基于建议的函数,我如何将每个击键发送到 google api 并获取建议并加载Qtextedit,有没有更好的方法来做到这一点
我正在尝试在 pyqt5 QLineEdit 中创建类似这样的内容(自动完成位置)。
有一个名为 QCompleter 的类,我可以用它来建议内容,但它需要一个已经形成的列表,但是这个 google places 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 的软件创建插件)。虽然它独立运行良好,所以也许它特定于我的平台。
最后,我找到了一个类似案例的 Qt 示例项目,Google Suggest。您可以在https://doc.qt.io/qt-5/qtnetwork-googlesuggest-example.html找到它。它创建了一个自定义类来处理搜索和弹出窗口(使用 QTreeWidget)。
由于示例在 Qt 中,我将其移植到 PyQt 并稍作修改https://github.com/ismailsunni/scripts/blob/master/autocomplete_from_url.py