[GIS] Running Python produces ‘No module named ‘PyQt4’ in Qgis on Mac High Sierra

macpyqtpyqt4pythonqgis

I was following the instructions in this guide: Create a Polygon Shapefile from Point data and fairly sure I substituted field variables to match my data. However, when I run the script on my Mac (High Sierra) I get the following messages:

exec(open('/var/folders/yw/x44kj4x96mx70gych38mvzcm0000gn/T/tmpr48c2xuz.py'.encode('utf-8')).read())
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/code.py", line 91, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
  File "<string>", line 2, in <module>
  File "/Applications/QGIS 3.app/Contents/MacOS/../Resources/python/qgis/utils.py", line 664, in _import
    mod = _builtin_import(name, globals, locals, fromlist, level)
ModuleNotFoundError: No module named 'PyQt4'

I even tried Installing PyQt4 On Mac OSX and Add to python path mac os x
but to no avail, still get the same error message.

Any thoughts here?

Here is the code I used:

import math
from PyQt4.QtCore import QVariant

def rotate(point, angle):
    angle *= math.pi / 180.
    px, py = point
    qx = math.cos(angle) * px - math.sin(angle) * py
    qy = math.sin(angle) * px + math.cos(angle) * py
    return qx, qy
def translate(point, translation):
    return point[0] + translation[0], point[1] + translation[1]

def rectangle(width, height, angle, center):
    p1 = (-width/2, -height/2)
    p2 = (-width/2, +height/2)
    p3 = (+width/2, +height/2)
    p4 = (+width/2, -height/2)
    rotated = [rotate(p, angle) for p in [p1, p2, p3, p4]]
    translated = [translate(p, center) for p in rotated]
    points = [QgsPoint(x, y) for x, y in translated]
    return points

in_layer = QgsMapLayerRegistry.instance().mapLayers().values()[0]

layer = QgsVectorLayer('Polygon?crs=epsg:2805', 'poly' , "memory")
pr = layer.dataProvider()
pr.addAttributes([QgsField("rate", QVariant.Double)])
layer.updateFields()
for feature in in_layer.getFeatures():
    geom = feature.geometry()
    p = geom.asPoint()

    width = 0.8*0.3048 * feature.attribute('width') / 100000 # MAGIC
    length = 1.2*0.3048 * feature.attribute('length') / 100000 # MAGIC
    direction = feature.attribute('angle')
    rate = feature.attribute('id_spaces')
    center = (p.x(), p.y())

    poly = QgsFeature()
    points = rectangle(width, length, -direction, center)
    poly.setGeometry(QgsGeometry.fromPolygon([points]))
    poly.setAttributes([rate])
    pr.addFeatures([poly])
layer.updateExtents()
QgsMapLayerRegistry.instance().addMapLayers([layer])

where I substituted 'width','length','angle','id_spaces' from my own point shapefile.

Best Answer

Are you using QGIS 3 or 2.x? One of the differences between those versions is that Qgis 3.0 uses Qt5 and Python 3.x, on the other hand Qgis 2 uses Qt4 and Python 2.7 . So, if you are following a tutorial made for 2.x, you have to make some changes.

As I can see for example: 1) the line that imports libraries, and 2) the line that adds the layer in your code.

from PyQt4.QtCore import QVariant

QgsMapLayerRegistry.instance().addMapLayers([layer])

in Qgis 3.0 must be changed to:

from PyQt5.QtCore import QVariant

QgsProject.instance().addMapLayers([layer])