Question

I've seen some topics here with the error: "TypeError: Argument must be rect style object". I'm having this error endlessly.

I've read the docs:

Rect(left, top, width, height) -> Rect
Rect((left, top), (width, height)) -> Rect
Rect(object) -> Rect

I have a method to extract subsurfaces from a pygame.Surface (It uses the surface's original method):

def getSubSurface(self, rect):

    """
    Returns the subsurface of a specified rect area in the grict surface.
    """

    return self.surface.subsurface(rect)

The problem is when I pass this rect (I've "unclustered" the arguments to make it clearer):

sub = []
w = self.tileWidth
h = self.tileHeight
for i in range((self.heightInPixels/self.heightInTiles)):
    y = self.grid.getY(i)
    for j in range((self.widthInPixels/self.widthInTiles)):
        x = self.grid.getX(j)
        sub.append(self.tileset.getSubSurface(pygame.Rect(x,y,w,h)))

I've explicitly passed a valid pygame.Rect, and I'm blitting nothing nowhere, and I get:

sub.append(self.tileset.getSubSurface(pygame.Rect(x,y,w,h)))
TypeError: Argument must be rect style object

Now, the funny part is: If I change the arguments to arbitrary int values:

sub.append(self.tileset.getSubSurface((1,2,3,4)))

It works perfectly. The pygame subsurfaces method takes it as a valid Rect. Problem is: All my instance-variables are valid ints (Even if they were not, it does not work if I convert them explicitly).

It makes no sense.

Why it takes explicit ints, but does not take my variables? (If the values were of an incorrect type, I would not get a "rectstyle" error, as if I was passing arguments incorrectly).

Was it helpful?

Solution

This error occurs if any of the arguments passed to Rect() are not numeric values.

To see what's wrong, add the following code to your method:

import numbers
...
sub = []
w = self.tileWidth
h = self.tileHeight
for i in range((self.heightInPixels/self.heightInTiles)):
    y = self.grid.getY(i)
    for j in range((self.widthInPixels/self.widthInTiles)):
        x = self.grid.getX(j)
        # be 100% sure x,y,w and h are really numbers
        assert isinstance(x, numbers.Number)
        assert isinstance(y, numbers.Number)
        assert isinstance(w, numbers.Number)
        assert isinstance(h, numbers.Number)
        sub.append(self.tileset.getSubSurface(pygame.Rect(x,y,w,h)))

OTHER TIPS

I've found the source of the problem. I've explicitly converted the variables to ints:

sub.append(self.tileset.getSubSurface((int(x),int(y),int(w),int(h))))

And got a "TypeError: int() argument must be a string or a number, not 'NoneType'" It became clear. The "x" and "y" variables in my iterations were returning a single "None" at the end (Because they were getting their values from a dictionary, and, since they stopped finding keys, they began returning a NoneType).

I've solved the problem fixing my getX and getY methods:

def getX(self, pos):

    """
    The getX() method expects a x-key as an argument. It returns its equivalent value in pixels.
    """

    if self.x.get(pos) != None:
        return self.x.get(pos)
    else:
        return 0 # If it is NoneType, it returns an acceptable Rect int value.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top