How to make wxPython, DC background transparent? - c++

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

Related

argument 1 must be pygame.Surface, not Window

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!

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 inherit from QWidget in PyQt?

Maigcally I can't inherit from QWidget using PyQt 4:
from PyQt4.QtGui import QApplication, QMainWindow, QWidget
class MyWidget(QWidget):
pass
if __name__ == "__main__":
app = QApplication([])
window = QMainWindow()
window.resize(200, 200)
widget1 = MyWidget(window)
widget1.resize(100, 100)
widget1.setStyleSheet("background-color:#FFFFFF")
window.show()
app.exec_()
It doesn't work. I just can't see the widget. But, using QLabel instead of QWidget works.
Thanks.
Solution
Reimplement paintEvent:
class MyWidget(QWidget):
def paintEvent(self, event):
o = QStyleOption()
o.initFrom(self)
p = QPainter(self)
self.style().drawPrimitive(QStyle.PE_Widget, o, p, self)
You are subclassing correctly. The "problem" is just that the QWidget has the same background colour as the main window (your call to setStyleSheet is not working).
As proof, run this code from a terminal:
from PyQt4.QtGui import QApplication, QMainWindow, QWidget, QLabel
class MyWidget(QWidget):
def enterEvent(self, evt):
print 'a'
if __name__ == "__main__":
app = QApplication([])
window = QMainWindow()
window.resize(200, 200)
widget1 = MyWidget(window)
widget1.resize(100, 100)
widget1.setStyleSheet("background-color:#FFFFFF")
window.show()
app.exec_()
When you move your mouse into the first 100,100 pixel square, you will see the letter 'a' being printed in the terminal