argument 1 must be pygame.Surface, not Window - python-2.7

Not sure if what I am trying to do is wrong or impossible. Here is my code:
import pygame
class Window(object):
def __init__(self, (width, height), color, cap=' '):
self.width = width
self.height = height
self.color = color
self.cap = cap
self.screen = pygame.display.set_mode((self.width, self.height))
def display(self):
self.screen
#screen =
pygame.display.set_caption(self.cap)
self.screen.fill(self.color)
class Ball(object):
def __init__(self, window, (x, y), color, size, thick=None):
self.window = window
self.x = x
self.y = y
self.color = color
self.size = size
self.thick = thick
def draw(self):
pygame.draw.circle(self.window, self.color, (self.x, self.y),
self.size, self.thick)
def main():
black = (0, 0, 0)
white = (255, 255, 255)
screen = Window((600, 600), black, 'Pong')
screen.display()
ball = Ball(screen, (300, 300), white, 5)
ball.draw()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.flip()
pygame.quit()
main()
This is the error I get:
Traceback (most recent call last):
File "C:\Users\acmil\Desktop\Team 7\newPongLib.py", line 47, in <module>
main()
File "C:\Users\acmil\Desktop\Team 7\newPongLib.py", line 36, in main
ball.draw()
File "C:\Users\acmil\Desktop\Team 7\newPongLib.py", line 28, in draw
self.size, self.thick)
TypeError: argument 1 must be pygame.Surface, not Window
I don't understand if i make a Window object why it won't draw a ball to the screen. Any help is appreciated.

Change your Ball class to the following:
class Ball(object):
def __init__(self, window, (x, y), color, size, thick=0):
self.window = window
self.x = x
self.y = y
self.color = color
self.size = size
self.thick = thick
def draw(self):
pygame.draw.circle(self.window.screen, self.color, (self.x, self.y),
self.size, self.thick)
I made two modifications to your code.
First, as for the error you were getting, you were passing in a custom Window object that you had defined instead of the pygame's Screen object that pygame was expecting. Check out the documentation on this function here.
Second, your original constructor defined thick=None by default, but that pygame function expects an int, so I changed it to thick=0.
It should work after these two changes. Let me know if you still are having issues!

Related

Gravity With Rects Pygame

I really have a basic question with a long awnser needed. Can someone show me how to make a Rect jump? I just need a sample with a rectangle.
I see your question and i think i have made some example code for you, but first i want to tell you how it works. In addition to an Y variable to store your location on the Y axis you want a variable called velocityY. For every frame in the game the Y variable is changed with velocityY like this:
while True:
y += velocityY # <----- Here
manage_window()
for event in pygame.event.get():
handle_event(event)
pygame.display.flip()
When you jump you set velocityY to lets say -10 and that will make your rect fly off into the sky, so we need to add gravity. Here is the long example (The important part is):
import pygame
pygame.init()
window = pygame.display.set_mode((800, 600))
x, y = 300, 400
xVelocity, yVelocity = 0, 0
rect = pygame.Rect(x, y, 200, 200)
groundRect = pygame.Rect(0, 500, 800, 100)
clock = pygame.time.Clock()
white = 255, 255, 255
red = 255, 0, 0
black = 0, 0, 0
blue = 0, 0, 255
while True:
clock.tick(60) # Make sure the game is running at 60 FPS
rect = pygame.Rect(x, y, 200, 200) # Updating our rect to match coordinates
groundRect = pygame.Rect(0, 500, 800, 100) # Creating ground rect
# HERE IS WHAT YOU CARE ABOUT #
yVelocity += 0.2 # Gravity is pulling the rect down
x += xVelocity # Here we update our velocity on the X axis
y += yVelocity # Here we update our velocity on the Y axis
# HERE IS WHAT YOU CARE ABOUT #
if groundRect.colliderect(rect): # Check if the rect is colliding with the ground
y = groundRect.top-rect.height
yVelocity = 0
window.fill(white)
pygame.draw.rect(window, red, rect) # Here we draw the rect
pygame.draw.rect(window, black, rect, 5) # Here we draw the black box around the rect
pygame.draw.rect(window, blue, groundRect) # Here we draw the ground
pygame.draw.rect(window, black, groundRect, 5) # Here we draw the black box around the rect
for event in pygame.event.get(): # Getting events
if event.type == pygame.QUIT: # If someone presses X on the window, then we want to quit
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE: # Pressing space will make the cube jump
if y >= 300: # Checking if cube is on the ground and not in the air
yVelocity = -10 # Setting velocity to upwards
pygame.display.flip() # Updating the screen

Raspberry pi Video Capture freezes while writing to video

I am trying to display the webcam stream as well as write the video to a file simultaneously.But while am writing, it freezes the live stream. The problem is that OpenCV uses a loop to record video,the program gets stuck in the OpenCV loop and the user is unable to continue.It doesn't listen for user response. How can i simultaneously record video and listen for user responses?
code iam using :
import wx
import vlc
import os
import user
import numpy as np
import time
import cv, cv2
class MainWindow(wx.Panel):
def __init__(self, parent,capture):
wx.Panel.__init__(self, parent)
mainSizer = wx.BoxSizer(wx.VERTICAL)
# video
videoWarper = wx.StaticBox(self,size=(640,480)
videoBoxSizer = wx.StaticBoxSizer(videoWarper, wx.VERTICAL)
videoFrame = wx.Panel(self, -1,size=(640,480))
capture = ShowCapture(videoFrame, capture)
videoBoxSizer.Add(videoFrame,0)
mainSizer.Add(videoBoxSizer,0)
parent.Centre()
self.Show()
self.SetSizerAndFit(mainSizer)
# Panels
# The first panel holds the video and it's all black
self.videopanel = wx.Panel(self, -1)
self.videopanel.SetBackgroundColour(wx.BLACK)
# The second panel holds controls
ctrlpanel = wx.Panel(self, -1 )
self.timeslider = wx.Slider(ctrlpanel, -1, 0, 0, 1000)
self.timeslider.SetRange(0, 1000)
record = wx.Button(ctrlpanel, label="Record")
end = wx.Button(ctrlpanel, label="End")
# Bind controls to events
self.Bind(wx.EVT_BUTTON, self.OnRecord, record)
self.Bind(wx.EVT_BUTTON, self.OnEnd, end)
# Give a pretty layout to the controls
ctrlbox = wx.BoxSizer(wx.VERTICAL)
box = wx.BoxSizer(wx.HORIZONTAL)
# box contains some buttons and the volume controls
box.Add(record)
box.Add(end)
# Merge box to the ctrlsizer
ctrlbox.Add(box, flag=wx.EXPAND, border=10)
ctrlpanel.SetSizer(ctrlbox)
# Put everything togheter
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(ctrlpanel, flag=wx.EXPAND | wx.BOTTOM | wx.TOP, border=10)
self.SetSizer(sizer)
self.SetMinSize((350, 300))
# VLC player controls
self.Instance = vlc.Instance()
self.player = self.Instance.media_player_new()
def OnRecord(self, evt):
fourcc = cv2.cv.CV_FOURCC('D', 'I', 'V', 'X')
out = cv2.VideoWriter('video.avi', fourcc, 8.0, (640, 480))
counter = 0
while counter < 1:
ret,frame = capture.read()
out.write(frame)
def OnEnd(self, evt):
out = cv2.VideoWriter('video.avi', fourcc, 8.0, (640, 480))
out.release()
cv2.destroyAllWindows()
class ShowCapture(wx.Panel):
def __init__(self, parent, capture, fps=8):
wx.Panel.__init__(self, parent, wx.ID_ANY, (0,0), (640,480))
self.capture = capture
ret, frame = capture.read()
height, width = frame.shape[:2]
parent.SetSize((width, height))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
self.bmp = wx.BitmapFromBuffer(width, height, frame)
self.timer = wx.Timer(self)
self.timer.Start(1000./fps)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_TIMER, self.NextFrame)
def OnPaint(self, evt):
dc = wx.BufferedPaintDC(self)
dc.DrawBitmap(self.bmp, 0, 0)
def NextFrame(self, event):
ret, frame = self.capture.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
self.bmp.CopyFromBuffer(frame)
self.Refresh()
capture = cv2.VideoCapture(-1)
app = wx.App(False)
frame = wx.Frame(None, title='CamGUI')
panel = MainWindow(frame, capture)
frame.Show()
app.MainLoop()
Does raspberry pi capable of Read/write the video parallely or it hurts the performance of pi?
Hope for experts advice :)
Add a timer, that will allow you to test for input and other changes during the execution of the application.
wx.timer

Raspberry pi VideoCapture freezes while Recording

I have been trying to save the webcam stream of the raspberry pi using opencv videocapture.
My code is:
import wx
import vlc
import os
import user
import numpy as np
import time
import cv, cv2
class MainWindow(wx.Panel):
def __init__(self, parent,capture):
wx.Panel.__init__(self, parent)
mainSizer = wx.BoxSizer(wx.VERTICAL)
# video
videoWarper = wx.StaticBox(self,size=(640,480)
videoBoxSizer = wx.StaticBoxSizer(videoWarper, wx.VERTICAL)
videoFrame = wx.Panel(self, -1,size=(640,480))
capture = ShowCapture(videoFrame, capture)
videoBoxSizer.Add(videoFrame,0)
mainSizer.Add(videoBoxSizer,0)
parent.Centre()
self.Show()
self.SetSizerAndFit(mainSizer)
# Panels
# The first panel holds the video and it's all black
self.videopanel = wx.Panel(self, -1)
self.videopanel.SetBackgroundColour(wx.BLACK)
# The second panel holds controls
ctrlpanel = wx.Panel(self, -1 )
self.timeslider = wx.Slider(ctrlpanel, -1, 0, 0, 1000)
self.timeslider.SetRange(0, 1000)
record = wx.Button(ctrlpanel, label="Record")
end = wx.Button(ctrlpanel, label="End")
# Bind controls to events
self.Bind(wx.EVT_BUTTON, self.OnRecord, record)
self.Bind(wx.EVT_BUTTON, self.OnEnd, end)
# Give a pretty layout to the controls
ctrlbox = wx.BoxSizer(wx.VERTICAL)
box = wx.BoxSizer(wx.HORIZONTAL)
# box contains some buttons and the volume controls
box.Add(record)
box.Add(end)
# Merge box to the ctrlsizer
ctrlbox.Add(box, flag=wx.EXPAND, border=10)
ctrlpanel.SetSizer(ctrlbox)
# Put everything togheter
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(ctrlpanel, flag=wx.EXPAND | wx.BOTTOM | wx.TOP, border=10)
self.SetSizer(sizer)
self.SetMinSize((350, 300))
# VLC player controls
self.Instance = vlc.Instance()
self.player = self.Instance.media_player_new()
def OnRecord(self, evt):
fourcc = cv2.cv.CV_FOURCC('D', 'I', 'V', 'X')
out = cv2.VideoWriter('video.avi', fourcc, 8.0, (640, 480))
counter = 0
while counter < 1:
ret,frame = capture.read()
out.write(frame)
def OnEnd(self, evt):
out = cv2.VideoWriter('video.avi', fourcc, 8.0, (640, 480))
out.release()
cv2.destroyAllWindows()
class ShowCapture(wx.Panel):
def __init__(self, parent, capture, fps=8):
wx.Panel.__init__(self, parent, wx.ID_ANY, (0,0), (640,480))
self.capture = capture
ret, frame = capture.read()
height, width = frame.shape[:2]
parent.SetSize((width, height))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
self.bmp = wx.BitmapFromBuffer(width, height, frame)
self.timer = wx.Timer(self)
self.timer.Start(1000./fps)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_TIMER, self.NextFrame)
def OnPaint(self, evt):
dc = wx.BufferedPaintDC(self)
dc.DrawBitmap(self.bmp, 0, 0)
def NextFrame(self, event):
ret, frame = self.capture.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
self.bmp.CopyFromBuffer(frame)
self.Refresh()
capture = cv2.VideoCapture(-1)
app = wx.App(False)
frame = wx.Frame(None, title='CamGUI')
panel = MainWindow(frame, capture)
frame.Show()
app.MainLoop()
I have managed to get a video stream inside a GUI window but it freezes after i start Record a video and Livestream get struck up though it keep recording in background, until i close the python shell.
What might be the reason?

Logically zooming in/out in canvas

I want to create one canvas widget, which allows user to draw on it. I am using canvas.bind for it. What I want is the size of canvas should be 32x32 originally, but when it is displayed, it should be like zoomed version of original widget, without resizing the original canvas. I have to use smaller size ( 32x32 ) for further processing on the drawn picture. Meaning if canvas size is 32x32 then it should be displayed as 512x512 size for drawing purpose , but 32x32 size for processing purpose. I tried with canvas.Scale but it seems that it will not be helpful for this purpose because it resizes original widget. Can someone please guide me? I use python2.7.
Thanks!
If I completely understand your problem, then I think this would be your solution:
from __future__ import division
import Tkinter
ORIGINAL_WIDTH = 32
ORIGINAL_HEIGHT = 32
WINDOW_WIDTH = 512
WINDOW_HEIGHT = 512
WIDTH_RATIO = WINDOW_WIDTH/ORIGINAL_WIDTH
HEIGHT_RATIO = WINDOW_HEIGHT/ORIGINAL_HEIGHT
class App(Tkinter.Tk):
def __init__(self, *args, **kwargs):
Tkinter.Tk.__init__(self, *args, **kwargs)
self.canvas = canvas = Tkinter.Canvas( self,
highlightthickness = 0,
width = WINDOW_WIDTH,
height = WINDOW_HEIGHT )
self.canvas.pack()
# Create a list for holding canvas objects
self.scene = []
# Draw objects and scale them
self.draw()
self.zoom()
def draw(self):
canvas = self.canvas
# Draw rectangles within the range of 0..32 x 0..32
rect1 = canvas.create_rectangle( 2, 0, 30, 2, fill='black' )
rect2 = canvas.create_rectangle( 0, 2, 2, 30, fill='black' )
rect3 = canvas.create_rectangle( 30, 2, 32, 30, fill='black' )
rect4 = canvas.create_rectangle( 2, 30, 30, 32, fill='black' )
rect5 = canvas.create_rectangle( 10, 10, 22, 22, fill='black' )
self.scene.extend( (rect1, rect2, rect3, rect4, rect5) )
def zoom(self):
canvas = self.canvas
# Scale all objects on scene
for item in self.scene:
canvas.scale( item, 0, 0, WIDTH_RATIO, HEIGHT_RATIO )
App().mainloop()

How to make wxPython, DC background transparent?

How can i make the default white DC background become invisible (transparent)?
Run the following example, it shows a white background over a button. I would like to remove the white background of the DC. (to show only the red X)
import wx
class drawover(wx.Window):
def __init__(self, parent):
wx.Window.__init__(self, parent)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnErase)
self.Bind(wx.EVT_SET_FOCUS, self.OnFocus)
def OnFocus(self, evt):
self.GetParent().SetFocus()
def OnErase(self, evt):
pass
def OnPaint(self, evt):
dc = wx.PaintDC(self)
dc.BeginDrawing()
dc.SetPen(wx.Pen("RED", 1))
dc.DrawLineList([(0,0,100,100), (100,0,0,100)])
dc.EndDrawing()
class frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, size=(600,600))
s = wx.BoxSizer(wx.VERTICAL)
self.tc1 = wx.TextCtrl(self, style=wx.TE_MULTILINE)
s.Add(self.tc1, 1, wx.EXPAND)
self.tc2 = wx.Button(self)
s.Add(self.tc2, 1, wx.EXPAND)
self.d = drawover(self.tc2)
self.tc2.Bind(wx.EVT_SIZE, self.OnSize2)
self.SetSizer(s)
self.Layout()
def OnSize2(self, evt):
self.d.SetSize((101,101))
if __name__ == '__main__':
a = wx.App(0)
b = frame()
b.Show(1)
a.MainLoop()
http://wiki.wxpython.org/Transparent%20Frames
If you are on windows just see above.
If not you basically have to capture the frame below it as an image and paint it (in your onpaint) to fake it
also see
http://wxpython-users.1045709.n5.nabble.com/Transparent-Panels-td2303275.html