You are trying to construct a polygon with a long list of coordinates, that won't do. List of points is how you define a polyline, yet QgsGeometry::fromPolygon() expects a polygon.
Moreso, you want to create many polygons, yet you are feeding it only one sequential list of all coordinates, hence why it's creating one polygon that goes through each coordinate.
Polygons are defined as a closed loop linestring. Polygons with rings inside them (as in a donut) are defined with one closed loop linestring for its exterior ring (the outer boundary) and one for its inner ring (the inner boundary). You do this in PyQGIS with a list of lists, where each inner list is a closed loop list of coordinates. As such:
from qgis.core import QgsGeometry, QgsPoint
# Define exterior ring coordinates, notice how the first point repeats at the end of the list.
p1 = QgsPoint(0, 0)
p2 = QgsPoint(10, 0)
p3 = QgsPoint(10, 10)
p4 = QgsPoint(0, 10)
li_out_ring = [p1, p2, p3, p4, p1]
# Define interior ring coordinates, notice how the first point repeats at the end of the list.
p5 = QgsPoint(2, 2)
p6 = QgsPoint(8, 2)
p7 = QgsPoint(8, 8)
p8 = QgsPoint(2, 8)
li_inn_ring = [p5, p6, p7, p8, p5]
# Creates geometry.
polygon = QgsGeometry.fromPolygon([li_ext_ring, li_inn_ring])
This is the result:

You'll have to repeat that for every polygon you want to create that comprises your final shape.
UPDATE: What to do when you have a list of coordinates without distinction between inner and outer rings?
If your polygon only has one inner ring, and your exterior ring has a convex shape (which is the case of a donut), you can find it and separate the geometries. How you do this is, you first collect all your points into one Multipoint geometry. Then you find the exterior ring by creating a Convex Hull. Finally, you compare the points that are in the convex hull geometry with the full set of points, and whichever points are left out will be part of the inner ring.
def create_wkt_from_list(li_points):
# li_points must be a python list() of QgsPoint objects.
wkt = 'MULTIPOINT('
for point in li_points:
x = point.x()
y = point.y()
wkt += '({} {}), '.format(x, y)
wkt = wkt[:-1] + ')'
return wkt
wkt = create_wkt_from_list(li_points)
multipoint = QgsGeometry.fromWkt(wkt)
out_ring = multipoint.convexHull()
From here you can construct an iterator which will go through every vertex of your out_ring and compare it with your initial list, or something like it. There's probably a more efficient way to do it, but this is the gist of it.
What if my polygon isn't convex? There are methods to finding the Concave Hull, but they are not deterministic, hence do not bode well to differentiating between outer and inner rings.
What if my polygon has many inner rings? The method above will still work, but there will be no way of differentiating between the rings, so you'll end up with only one, likely weirdly-shaped, inner ring.