At this point, we are almost done. The last thing that has to happen is connecting the widgets’ relevant signals to the corresponding slots or event handler functions. For this, please add the following code under the comment “# connect signals”:
ui.runQueryPB.clicked.connect(runQuery) ui.resultsClearSelectionPB.clicked.connect(clearSelection) ui.resultsSelectAllPB.clicked.connect(selectAll) ui.resultsInvertSelectionPB.clicked.connect(invertSelection) ui.shapefileOpenFileTB.clicked.connect(selectShapefile) ui.addFeatureAddPB.clicked.connect(addFeatures) ui.shapefileCreateNewPB.clicked.connect(createNewShapefile) ui.csvOpenFileTB.clicked.connect(selectCSV) ui.layerRefreshTB.clicked.connect(updateLayers) ui.shapefileAddLE.editingFinished.connect(updateShapefileFieldCB) ui.layerPickLayerCB.activated.connect(updateLayerFieldCB) createShapefileDialog_ui.newShapefileBrowseTB.clicked.connect(selectNewShapefile)
Lines 1 to 9 and line 13 all connect “clicked” signals of different buttons in our GUI to the different event handler functions defined previously and should be easy to understand. In line 10, the “editingFinished” signal of the text field for entering the name of a shapefile is connected with the updateShapefileFieldCB() function so that, whenever the name of the shapefile is changed, the list of the fields in the combo box is updated accordingly. In line 11, we connect the “activated” signal of the combo box for selecting a layer with the upateLayerFields() function. As a result, the second combo box with the field names will be updated whenever the layer selected in the first combo box on the Layer tab is changed.
That’s it. The program is finished and can be tested and used either as a standalone application (writing features either to a shapefile or to a .csv file) or as an ArcGIS script tool. Give it a try yourself and think about which parts of the code are being executed when performing different operations. In case you want to run it as a script tool inside ArcGIS Pro, setting up the script tool for it should be straightforward. You just have to create a new script tool without specifying any parameters and provide the path to the main.py script for the source. If you have any problems running the code with your own script, the entire code can be downloaded via this link to the Locations from Web Services Complete zip file. If something in the code above is unclear to you, please ask about it on the course forums.
Obviously, the tool is still somewhat basic and could be extended in many ways including:
- providing more query options for the currently implemented query services
- incorporating other web services
- allowing for multiple query terms as input (e.g. list of place names or addresses); it could also be useful to be able to paste some longer text into the tool and then highlight place names in the text that should be queried
- supporting other geometries, not just points
- … (add your own ideas to the list)
Moreover, while we included some basic error handling with try-except, the program is not completely bullet proof and in some cases it would be desirable to provide more direct and specific feedback to the user, for instance if the user enters something into the feature class field of the GeoNames query tab that is not a valid feature class code. We are also quietly assuming that the shapefile or layer we are adding to is using a WGS1984 geographical coordinate system. Adding reprojection of the input features to the CRS of the destination would certainly be a good thing to do.
Still, the tool can be useful for creating point feature classes of locations of interest very quickly and in a rather convenient way. More importantly, this walkthrough should have provided you with a better understanding of how to create Python programs with a GUI by roughly separating the code into a part for setting up the GUI elements, a part for realizing the actual functionality (in this case the part defining the different event handler functions (GUI dependent) with the help of the core functions from core_functions.py (GUI independent)), and a part that makes the connection between the other two parts based on GUI events. You will practice creating GUIs and PyQt5 based Python programs yourself in this lesson’s homework assignment and also again in lesson 4. But for now, we will continue with looking at another aspect of creating and publishing Python applications, namely that of package management and packaging Python programs so that they can easily be shared with others.