Python-GUI-编程(八)

Python GUI 编程(八)

原文:zh.annas-archive.org/md5/9d5f7126bd532a80dd6a9dce44175aaa

译者:飞龙

协议:CC BY-NC-SA 4.0

第二十二章:使用谷歌地图

在本章中,您将学习如何在 Python 应用程序中使用谷歌地图,并探索谷歌提供的不同优势。您将学习以下任务:

  • 查找位置或地标的详细信息

  • 从经度和纬度值获取完整信息

  • 查找两个位置之间的距离

  • 在谷歌地图上显示位置

介绍

谷歌地图 API 是一组方法和工具,可用于查找任何位置的完整信息,包括经度和纬度值。您可以使用谷歌地图 API 方法查找两个位置之间的距离或到达任何位置的方向;甚至可以显示谷歌地图,标记该位置,等等。

更准确地说,谷歌地图服务有一个 Python“客户端”库。谷歌地图 API 包括方向 API、距离矩阵 API、地理编码 API、地理位置 API 等多个 API。要使用任何谷歌地图网络服务,您的 Python 脚本会向谷歌发送一个请求;为了处理该请求,您需要一个 API 密钥。您需要按照以下步骤获取 API 密钥:

  1. 访问console.developers.google.com

  2. 使用您的谷歌账号登录控制台

  3. 选择您现有的项目之一或创建一个新项目。

  4. 启用您想要使用的 API

  5. 复制 API 密钥并在您的 Python 脚本中使用它

您需要访问谷歌 API 控制台,console.developers.google.com,并获取 API 密钥,以便您的应用程序经过身份验证可以使用谷歌地图 API 网络服务。

API 密钥在多个方面有帮助;首先,它有助于识别您的应用程序。API 密钥包含在每个请求中,因此它有助于谷歌监视您的应用程序的 API 使用情况,了解您的应用程序是否已经消耗完每日的免费配额,并因此向您的应用程序收费。

因此,为了在您的 Python 应用程序中使用谷歌地图 API 网络服务,您只需要启用所需的 API 并获取一个 API 密钥。

查找位置或地标的详细信息

在这个教程中,您将被提示输入您想要了解的位置或地标的详细信息。例如,如果您输入“白金汉宫”,该教程将显示宫殿所在地的城市和邮政编码,以及其经度和纬度值。

如何做…

GoogleMaps类的 search 方法是这个教程的关键。用户输入的地标或位置被传递给 search 方法。从 search 方法返回的对象的citypostal_codelatlng属性用于分别显示位置的城市、邮政编码、纬度和经度。让我们通过以下逐步过程来看看如何完成这个操作:

  1. 基于无按钮对话框模板创建一个应用程序。

  2. 通过将六个标签、一个行编辑和一个推送按钮小部件拖放到表单上,向表单添加六个标签、一个行编辑和一个推送按钮小部件。

  3. 将第一个标签小部件的文本属性设置为“查找城市、邮政编码、经度和纬度”,将第二个标签小部件的文本属性设置为“输入位置”。

  4. 删除第三、第四、第五和第六个标签小部件的文本属性,因为它们的文本属性将通过代码设置;也就是说,输入位置的城市、邮政编码、经度和纬度将通过代码获取并通过这四个标签小部件显示。

  5. 将推送按钮小部件的文本属性设置为“搜索”。

  6. 将行编辑小部件的 objectName 属性设置为lineEditLocation

  7. 将推送按钮小部件的 objectName 属性设置为pushButtonSearch

  8. 将其余四个标签小部件的 objectName 属性设置为labelCitylabelPostalCodelabelLongitudelabelLatitude

  9. 将应用程序保存为demoGoogleMap1.ui。表单现在将显示如下屏幕截图所示:

使用 Qt Designer 创建的用户界面存储在.ui文件中,它是一个 XML 文件。通过应用pyuic5实用程序将 XML 文件转换为 Python 代码。您可以在本书的源代码包中找到生成的 Python 代码demoGoogleMap1.py

  1. demoGoogleMap1.py脚本视为头文件,并将其导入到将调用其用户界面设计的文件中。

  2. 创建另一个名为callGoogleMap1.pyw的 Python 文件,并将demoGoogleMap1.py代码导入其中:

import sys
from PyQt5.QtWidgets import QDialog, QApplication
from geolocation.main import GoogleMaps
from demoGoogleMap1 import *
class MyForm(QDialog):
    def __init__(self):
        super().__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.ui.pushButtonSearch.clicked.connect(self.
        displayDetails)
        self.show()
    def displayDetails(self):
        address = str(self.ui.lineEditLocation.text())
        google_maps = GoogleMaps(api_key=
        'xxxxxxxxxxxxxxxxxxxxxxxxxxxx')
        location = google_maps.search(location=address)
        my_location = location.first()
        self.ui.labelCity.setText("City: 
        "+str(my_location.city))
        self.ui.labelPostalCode.setText("Postal Code: " 
        +str(my_location.postal_code))
        self.ui.labelLongitude.setText("Longitude: 
        "+str(my_location.lng))
        self.ui.labelLatitude.setText("Latitude: 
        "+str(my_location.lat))
if __name__=="__main__":
    app = QApplication(sys.argv)
    w = MyForm()
    w.show()
    sys.exit(app.exec_())

它是如何工作的...

您可以在脚本中看到,具有 objectName 属性pushButtonSearch的按钮的单击事件连接到displayDetails方法。这意味着每当单击按钮时,将调用displayDetails方法。在displayDetails方法中,您访问用户在行编辑小部件中输入的位置,并将该位置分配给地址变量。通过传递在 Google 注册时获得的 API 密钥来定义 Google Maps 实例。在 Google Maps 实例上调用search方法,传递用户在此方法中输入的位置。search方法的结果分配给my_location结构。my_location结构的 city 成员包含用户输入的城市。类似地,my_location结构的postal_codelnglat成员分别包含用户输入位置的邮政编码、经度和纬度信息。城市、邮政编码、经度和纬度信息通过最后四个标签小部件显示。

运行应用程序时,将提示您输入要查找信息的位置。假设您在位置中输入泰姬陵,然后单击搜索按钮。泰姬陵地标的城市、邮政编码、经度和纬度信息将显示在屏幕上,如下面的屏幕截图所示:

从纬度和经度值获取完整信息

在本教程中,您将学习如何查找已知经度和纬度值的位置的完整详细信息。将点位置(即纬度和经度值)转换为可读地址(地名、城市、国家名称等)的过程称为反向地理编码

应用程序将提示您输入经度和纬度值,然后显示匹配的位置名称、城市、国家和邮政编码。

如何做...

让我们根据以下步骤创建一个基于无按钮对话框模板的应用程序:

  1. 通过将七个QLabel、两个QLineEdit和一个QPushButton小部件拖放到表单上,向表单添加七个标签、两个行编辑和一个按钮小部件。

  2. 将第一个标签小部件的文本属性设置为查找位置、城市、国家和邮政编码,将第二个标签小部件的文本属性设置为输入经度,将第三个标签小部件的文本属性设置为输入纬度

  3. 删除第四、第五、第六和第七个标签小部件的文本属性,因为它们的文本属性将通过代码设置;也就是说,用户输入经度和纬度的位置的位置、城市、国家和邮政编码将通过代码访问,并通过这四个标签小部件显示。

  4. 将 Push Button 小部件的文本属性设置为搜索

  5. 将两个行编辑小部件的 objectName 属性设置为lineEditLongitudelineEditLatitude

  6. 将 Push Button 小部件的 objectName 属性设置为pushButtonSearch

  7. 将其他四个标签小部件的 objectName 属性设置为labelLocationlabelCitylabelCountrylabelPostalCode

  8. 将应用程序保存为demoGoogleMap2.ui。表单现在将显示如下截图所示:

使用 Qt Designer 创建的用户界面存储在.ui文件中,这是一个 XML 文件,需要转换为 Python 代码。使用pyuic5实用程序将 XML 文件转换为 Python 代码。在本书的源代码包中可以看到生成的 Python 脚本demoGoogleMap2.py

  1. demoGoogleMap2.py脚本视为头文件,并将其导入到将调用其用户界面设计的文件中。

  2. 创建另一个名为callGoogleMap2.pyw的 Python 文件,并将demoGoogleMap2.py代码导入其中:

import sys
from PyQt5.QtWidgets import QDialog, QApplication
from geolocation.main import GoogleMaps
from demoGoogleMap2 import *
class MyForm(QDialog):
    def __init__(self):
        super().__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.ui.pushButtonSearch.clicked.connect(self.
        displayLocation)
        self.show()
    def displayLocation(self):
        lng = float(self.ui.lineEditLongitude.text())
        lat = float(self.ui.lineEditLatitude.text())
        google_maps = GoogleMaps(api_key=
        'AIzaSyDzCMD-JTg-IbJZZ9fKGE1lipbBiFRiGHA')
        my_location = google_maps.search(lat=lat, lng=lng).
        first()
        self.ui.labelLocation.setText("Location:   
        "+str(my_location))
        self.ui.labelCity.setText("City: 
        "+str(my_location.city))
        self.ui.labelCountry.setText("Country: 
        "+str(my_location.country))
        self.ui.labelPostalCode.setText("Postal Code: 
        "+str(my_location.postal_code))
if __name__=="__main__":
    app = QApplication(sys.argv)
    w = MyForm()
    w.show()
    sys.exit(app.exec_())

操作原理如下:

在脚本中,您可以看到具有 objectName 属性pushButtonSearch的推送按钮的 click()事件连接到displayLocation方法。这意味着每当单击推送按钮时,将调用displayLocation方法。在displayLocation方法中,您通过两个 Line Edit 小部件访问用户输入的经度和纬度,并分别将它们分配给两个变量lnglat。通过传递在 Google 注册时获得的 API 密钥来定义 Google Maps 实例。在 Google Maps 实例上调用search方法,传递用户提供的经度和纬度值。在检索到的搜索上调用first方法,并将与提供的经度和纬度值匹配的第一个位置分配给my_location结构。位置名称通过 Label 小部件显示。为了显示位置的城市、国家和邮政编码,使用my_location结构的citycountrypostal_code成员。

运行应用程序时,您将被提示输入经度和纬度值。与提供的经度和纬度相关的位置名称、城市、国家和邮政编码将通过四个标签小部件显示在屏幕上,如下截图所示:

查找两个位置之间的距离

在这个教程中,您将学习如何找出用户输入的两个位置之间的距离(以公里为单位)。该教程将简单地提示用户输入两个位置,然后单击“查找距离”按钮,两者之间的距离将被显示。

操作步骤如下:

让我们根据没有按钮模板的对话框创建一个应用程序,执行以下步骤:

  1. 通过将四个标签、两个行编辑和一个推送按钮小部件拖放到表单上,向表单添加四个QLabel、两个QLineEdit和一个QPushButton小部件。

  2. 将第一个标签小部件的文本属性设置为“查找两个位置之间的距离”,将第二个标签小部件的文本属性设置为“输入第一个位置”,将第三个标签小部件的文本属性设置为“输入第二个位置”。

  3. 删除第四个标签小部件的文本属性,因为它的文本属性将通过代码设置;也就是说,两个输入位置之间的距离将通过代码计算并显示在第四个标签小部件中。

  4. 将推送按钮小部件的文本属性设置为“查找距离”。

  5. 将两个行编辑小部件的 objectName 属性设置为lineEditFirstLocationlineEditSecondLocation

  6. 将推送按钮小部件的 objectName 属性设置为pushButtonFindDistance

  7. 将第四个标签小部件的 objectName 属性设置为labelDistance

  8. 将应用程序保存为demoGoogleMap3.ui。表单现在将显示如下截图所示:

使用 Qt Designer 创建的用户界面存储在.ui文件中,它是一个 XML 文件。通过应用pyuic5实用程序,将 XML 文件转换为 Python 代码。您可以在本书的源代码包中找到生成的 Python 代码demoGoogleMap3.py

  1. 要使用在demoGoogleMap3.py文件中创建的 GUI,我们需要创建另一个 Python 脚本并在该脚本中导入demoGoogleMap3.py文件。

  2. 创建另一个名为callGoogleMap3.pyw的 Python 文件,并将demoGoogleMap3.py代码导入其中:

import sys
from PyQt5.QtWidgets import QDialog, QApplication
from googlemaps.client import Client
from googlemaps.distance_matrix import distance_matrix
from demoGoogleMap3 import *
class MyForm(QDialog):
    def __init__(self):
        super().__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.ui.pushButtonFindDistance.clicked.connect(self.
        displayDistance)
        self.show()
    def displayDistance(self):
        api_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
        gmaps = Client(api_key)
        data = distance_matrix(gmaps,  
        self.ui.lineEditFirstLocation.text(),         
        self.ui.lineEditSecondLocation.text())
        distance = data['rows'][0]['elements'][0]['distance']
        ['text']
        self.ui.labelDistance.setText("Distance between 
        "+self.ui.lineEditFirstLocation.text()+" 
        and "+self.ui.lineEditSecondLocation.text()+" is 
        "+str(distance))
if __name__=="__main__":
    app = QApplication(sys.argv)
    w = MyForm()
    w.show()
    sys.exit(app.exec_())

它是如何工作的…

您创建一个Client类的实例并将其命名为gmaps。在创建Client实例时,您需要传递在注册 Google 时获得的 API 密钥。具有 objectNamepushButtonFindDistance的按钮的 click()事件连接到displayDistance方法。这意味着每当单击按钮时,将调用displayDistance方法。在displayDistance方法中,您调用distance_matrix方法,传递Client实例和用户输入的两个位置,以找出它们之间的距离。distance_matrix方法返回一个多维数组,该数组分配给数据数组。从数据数组中,访问并将两个位置之间的距离分配给distance变量。最终通过 Label 小部件显示distance变量中的值。

运行应用程序时,将提示您输入要了解其相隔距离的两个位置。输入两个位置后,单击查找距离按钮,两个位置之间的距离将显示在屏幕上,如下截图所示:

在 Google 地图上显示位置

在本教程中,您将学习如何在 Google 地图上显示位置,如果您知道该位置的经度和纬度值。您将被提示简单输入经度和纬度值,当您单击显示地图按钮时,该位置将显示在 Google 地图上。

如何做…

让我们创建一个基于无按钮对话框模板的应用程序,执行以下步骤:

  1. 通过将两个 Label、两个 Line Edit、一个 PushButton 和一个 QWidget 小部件拖放到表单上,向表单添加两个 QLabel、两个 QLineEdit、一个 QPushButton 和一个 QWidget 小部件。

  2. 将两个 Label 小部件的文本属性设置为LongitudeLatitude

  3. 将 Push Button 小部件的文本属性设置为Show Map

  4. 将两个 Line Edit 小部件的 objectName 属性设置为lineEditLongitudelineEditLatitude

  5. 将 Push Button 小部件的 objectName 属性设置为pushButtonShowMap

  6. 将应用程序保存为showGoogleMap.ui。现在,表单将显示如下截图所示:

  1. 下一步是将QWidget小部件提升为QWebEngineView,因为要显示 Google 地图,需要QWebEngineView。因为 Google 地图是一个 Web 应用程序,我们需要一个 QWebEngineView 来显示和与 Google 地图交互。

  2. 通过右键单击 QWidget 小部件并从弹出菜单中选择 Promote to ...选项来提升QWidget小部件。在出现的对话框中,将 Base class name 选项保留为默认的 QWidget。

  3. 在 Promoted class name 框中输入QWebEngineView,在 header file 框中输入PyQT5.QtWebEngineWidgets

  4. 单击 Promote 按钮,将QWidget小部件提升为QWebEngineView类,如下截图所示:

  1. 单击关闭按钮关闭 Promoted Widgets 对话框。使用 Qt Designer 创建的用户界面存储在.ui文件中,这是一个 XML 文件,需要转换为 Python 代码。使用pyuic5实用程序将 XML 文件转换为 Python 代码。生成的 Python 脚本showGoogleMap.py可以在本书的源代码包中找到。

  2. showGoogleMap.py脚本视为头文件,并将其导入到您将调用其用户界面设计的文件中。

  3. 创建另一个名为callGoogleMap.pyw的 Python 文件,并将showGoogleMap.py代码导入其中:

import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5.QtWebEngineWidgets import QWebEngineView
from showGoogleMap import *
class MyForm(QDialog):
    def __init__(self):
        super().__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.ui.pushButtonShowMap.clicked.connect(self.dispSite)
        self.show()
    def dispSite(self):
        lng = float(self.ui.lineEditLongitude.text())
        lat = float(self.ui.lineEditLatitude.text())
        URL="https://www.google.com/maps/@"+self.ui.
        lineEditLatitude.text()+","
        +self.ui.lineEditLongitude.text()+",9z"
        self.ui.widget.load(QUrl(URL))
if __name__=="__main__":
    app = QApplication(sys.argv)
    w = MyForm()
    w.show()
    sys.exit(app.exec_())

工作原理…

在脚本中,您可以看到具有 objectName 属性pushButtonShowMap的按钮的点击事件与dispSite()方法相连。这意味着,每当点击按钮时,将调用dispSite()方法。在dispSite()方法中,您通过两个 Line Edit 小部件访问用户输入的经度和纬度,并分别将它们分配给两个变量lnglat。然后,您创建一个 URL,从google.com调用 Google 地图,并传递用户输入的纬度和经度值。

URL 最初是以文本形式存在的,并且被强制转换为QUrl实例,并传递给被提升为QWebEngineView以显示网站的小部件。QUrl是 Qt 中提供多种方法和属性来管理 URL 的类。然后,通过QWebEngineView小部件显示具有指定纬度和经度值的 Google 地图。

运行应用程序时,您将被提示输入您想在 Google 地图上查看的位置的经度和纬度值。输入经度和纬度值后,当您点击“显示地图”按钮时,Google 地图将显示该位置,如下面的屏幕截图所示:

posted @ 2024-04-18 10:57  绝不原创的飞龙  阅读(12)  评论(0编辑  收藏  举报