Pygame compiled cursor string not giving enough data - pygame

I'm trying to compile a cursor string provided by pygame and set the cursor to it. However, only 2 of the necessary 4 arguments are returned from the string compiler.
pygame.mouse.set_cursor(*pygame.cursors.broken_x)
cursor = pygame.cursors.compile(pygame.cursors.sizer_x_strings)
Results in:
Traceback (most recent call last):
File "main.py", line 17, in __init__
pygame.mouse.set_cursor(*cursor)
TypeError: function takes exactly 4 arguments (2 given)

The premade strings in pygame.cursors.* don't contain any metadata about the cursor, only the raw string. To effectively use them, you have to also provide the size (width in characters and height in lines) of the cursor string.
Here's an example that uses that premade cursor:
import sys
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((640, 480))
cursor, mask = pygame.cursors.compile(pygame.cursors.sizer_x_strings, "X", ".")
cursor_sizer = ((24, 16), (7, 11), cursor, mask)
pygame.mouse.set_cursor(*cursor_sizer)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
screen.fill((120, 120, 120))
pygame.display.update()

Related

How can I load python wikipedia image in pygame display?

Alright, I am making as title, and here is this is part of codes.
black = (0,0,0)
display = pygame.display.set_mode((1000, 600))
def main():
search_word = "apple inc"
result = ""
main = True
while main:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
display.blit(black)
result = wikipedia.page(search_word)
display.blit(result.images[0], (100, 100)
pygame.display.update()
And, I got error:
Traceback (most recent call last):
display.blit(result.images[0], (100, 100)) AttributeError: 'str' object has no attribute 'images'
How can I fix it?
How can I fix it?
You can fix it by passing a Surface object to the blit function, not a string.
Pygame does not automatically download images from the internet for you. You have to download the images yourself; then you can use the functions in pygame.image to create Surface instances.

Pygame, copying the screen into an array

How do you get the screen contents into an array in pygame? I have tried this from the documentation:
self.screen.lock()
tmp_frame = pygame.surfarray.array3d(self.screen)
self.screen.unlock()
I have tried all sorts of things, such as using pixelcopy to get a copy of the surface first, but I always get a segmentation fault.
Fatal Python error: (pygame parachute) Segmentation Fault Aborted
(core dumped)
Is it because I am trying to copy from the screen directly?
This is what screen contains:
self.screen = pygl2d.display.set_mode((self.SCREEN_WIDTH, self.SCREEN_HEIGHT), pygame.DOUBLEBUF, depth=24)
And this is the definition of set_mode:
def set_mode(resolution=(0,0), flags=0, depth=0):
flags |= pygame.OPENGL
screen = pygame.display.set_mode(resolution, flags, depth)
init_gl()
return screen
Edit followup:
I also tried copying the screen surface into another surface first with
tmp_surface= self.screen.copy()
But I get
pygame.error: Cannot copy opengl display
So really, I suppose the question is how do you copy this opengl display contents into an array?
To anyone who might experience something similar:
I was not able to find a direct solution, all methods of accessing the hardware accelerated surface resulted in a segmentation error. (array3d,array2d,accessing a reference array pixels3d etc).
However, I was able to figure out a workaround. It appears that you are able to save images with
pygame.image.save(self.screen, 'output.png')
Similarly, you can do
string_image = pygame.image.tostring(self.screen, 'RGB')
temp_surf = pygame.image.fromstring(string_image,(self.SCREEN_WIDTH, self.SCREEN_HEIGHT),'RGB' )
tmp_arr = pygame.surfarray.array3d(temp_surf)
This should get you a numpy array of the screen contents.
import pygame
import numpy as np
import time
from pandas import *
pygame.init()
display = pygame.display.set_mode((350, 350))
x = np.arange(0, 300)
y = np.arange(0, 300)
X, Y = np.meshgrid(x, y)
Z = X + Y
Z = 255*Z/Z.max()
surf = pygame.surfarray.make_surface(Z)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
display.blit(surf, (0, 0))
pygame.display.update()
# Convert the window in black color(2D) into a matrix
window_pixel_matrix = pygame.surfarray.array2d(display)
print(window_pixel_matrix)
time.sleep(10)
pygame.quit()
COMMENT :
"pygame.surfarray.array2d()" is what you're looking for I guess.
Of course, you can use "pygame.surfarray.array3d()" function as well.
You can refer to the official website : "https://www.pygame.org/docs/ref/surfarray.html#pygame.surfarray.array2d"

Pygame Binding Menu items to functions (by clicking)

Modifying the Squirrel Eat Squirrel Pygame for a class project. Trying to add in a menu, with basic Start, Quit and Settings buttons. I have the buttons there, and they will light up as the mouse scrolls over them. However, I can't figure out how to call their respective functions when I click on them. I am trying to call them by this:
def runMenu(self):
mainloop = True
while mainloop:
self.__clock.tick(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
mainloop == False
if event.type == MOUSEBUTTONDOWN:
for item in self.__items:
#print(item)
if item.isMouseSelecting(pygame.mouse.get_pos()):
print(self.__functions)
self.__functions[item]() #HERE <----
I believe it is because I am using a dictionary in my if name == "main" (See below) therefore it's not actually the dictionary, but its referencing its location? If that makes sense. (i'm not very good at explaining it, so sorry)
if __name__ == "__main__":
screen = pygame.display.set_mode((640, 480), 0 , 32)
menuItems = ('Start', 'Quit', 'Settings')
functions = {'Start': main, 'Quit': terminate, 'Settings': None}
pygame.display.set_caption('Main Menu')
game = MainMenu(screen, functions, menuItems)
game.runMenu()
The error it gives me in shell:
>>> ================================ RESTART ================================
>>>
({'Start': <function main at 0x2969ab0>, 'Settings': None, 'Quit': <function terminate at 0x2969cf0>}, '#')
{'Start': <function main at 0x2969ab0>, 'Settings': None, 'Quit': <function terminate at 0x2969cf0>}
Traceback (most recent call last):
File "/Users/tjleggz/Documents/CS 110/squirrel/squirrel.py", line 501, in <module>
game.runMenu()
File "/Users/tjleggz/Documents/CS 110/squirrel/squirrel.py", line 138, in runMenu
self.__functions[item]() #cant call bc its not same object, just a ref to object or something???#
KeyError: <__main__.MenuItem object at 0x29758c8>
>>>
THANKS!
EDIT:
class MenuItem(pygame.font.Font):
def __init__(self, text, font=None, fontSize=30,
fontColor=(255, 255, 255), (posX, posY)=(0, 0)):
pygame.font.Font.__init__(self, font, fontSize) #initializes font module
self.__text = text
self.__fontSize = fontSize
self.__fontColor = fontColor
self.label = self.render(self.__text, 1, self.__fontColor) #not private??
self.width = self.label.get_rect().width
self.height = self.label.get_rect().height
self.__posX = posX
self.__posY = posY
self.position = posX, posY
def set_position(self, x, y):
self.position = (x, y)
self.__posX = x
self.__posY = y
def isMouseSelecting(self, (posX, posY)): #change to conditional?!
if (posX >= self.__posX and posX <= self.__posX + self.width) and \
(posY >= self.__posY and posY <= self.__posY + self.height):
return True
else:
return False
def setFontColor(self, rgbTuple):
self.fontColor = rgbTuple
self.label = self.render(self.__text, 1, self.fontColor)
Your self.items contains MenuItem objects, not strings which are the keys to your dictionary. You can work around this in a couple ways, for example you could use the __text attribute of MenuItem which is I think what you are looking for.
A better way to do this (instead of using a dictionary of functions like you are now) might be to pass an on_click function to each MenuItem instance you make, and then you just have to write
if item.isMouseSelecting(pygame.mouse.get_pos()):
item.on_click()
however you seem to be relatively new to programming, so you may just want to use the first suggestion.

Pygame: Simple Cosine Function

I'm attempting to call a simple cosine calculation. This is my code:
import pygame
from pygame.locals import *
import math
pygame.init()
screen = pygame.display.set_mode((480, 480))
myfont = pygame.font.SysFont("monospace", 15)
angle = 90*(math.pi/180)
while True:
adj = math.cos(angle)
display = myfont.render("opposite side: " + str(adj), 1, (255, 255, 0))
screen.blit(display, (100,40))
pygame.display.flip()
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
exit(0)
Since cos(90)*5=0, I would expect the code to display that value. Instead I receive the following:
6.12323399574e-17
This will happen with floating point arithmetic. You should truncate the value before displaying it to the user.

Why does changing a kernel parameter deplete my resources?

I made a very simple kernel below to practice CUDA.
import pycuda.driver as cuda
import pycuda.autoinit
import numpy as np
from pycuda.compiler import SourceModule
from pycuda import gpuarray
import cv2
def compile_kernel(kernel_code, kernel_name):
mod = SourceModule(kernel_code)
func = mod.get_function(kernel_name)
return func
input_file = np.array(cv2.imread('clouds.jpg'))
height, width, channels = np.int32(input_file.shape)
my_kernel_code = """
__global__ void my_kernel(int width, int height) {
// This kernel trivially does nothing! Hurray!
}
"""
kernel = compile_kernel(my_kernel_code, 'my_kernel')
if __name__ == '__main__':
for i in range(0, 2):
print 'o'
kernel(width, height, block=(32, 32, 1), grid=(125, 71))
# When I take this line away, the error goes bye bye.
# What in the world?
width -= 1
Right now, if we run the code above, execution proceeds through the first iteration of the for loop just fine. However, during the second iteration of the loop, I get the following error.
Traceback (most recent call last):
File "outOfResources.py", line 27, in <module>
kernel(width, height, block=(32, 32, 1), grid=(125, 71))
File "/software/linux/x86_64/epd-7.3-1-pycuda/lib/python2.7/site-packages/pycuda-2012.1-py2.7-linux-x86_64.egg/pycuda/driver.py", line 374, in function_call
func._launch_kernel(grid, block, arg_buf, shared, None)
pycuda._driver.LaunchError: cuLaunchKernel failed: launch out of resources
If I take away the line width -= 1, the error goes away. Why is that? Can't I change the parameter for a kernel the second time around? For reference, here is clouds.jpg.
Though the error message isn't particularly informative, note that you need to pass in a correctly casted width variable. So something like:
width = np.int32(width - 1)
should work.