Record opengl content from QWidget in a thread - multithreading

I use some software (Nuke) with GUI in PySide and I would to grab the content of a QGLWidget recognized in QWidget by PySide (weird) and encode it to video.
So, I can't use QGLWidget.grabFrameBuffer():
AttributeError: 'PySide.QtGui.QWidget' object has no attribute 'grabFrameBuffer'
I tried:
# Qwidget.render(QImage)
image = QtGui.QImage(child.width(),child.height(),QtGui.QImage.Format_RGB32)
child.render(image)
image.save( '/Volumes/LaCie_Work/_TMP/test/test0.png', 'PNG')
Result : http://i.imgur.com/YwTtR2q.png - Problem : Miss lot of elements
# Qwidget.render(QPixmap)
image = QtGui.QPixmap(child.size())
child.render(image)
image.save( '/Volumes/LaCie_Work/_TMP/test/test1.png', 'PNG')
Result : http://i.imgur.com/DqO1PBS.png - Problem : No ! (see further below)
# QPixmap.grabWidget(QWidget)
image = QtGui.QPixmap.grabWidget(child)
image.save( '/Volumes/LaCie_Work/_TMP/test/test2.png', 'PNG')
Result : http://i.imgur.com/9n9Hofy.png - Problem : Not exactly but ok.. (see further below)
# QPixmap.grabWindow(QWidget.winId())
image = QtGui.QPixmap.grabWindow(child.winId())
image.save( '/Volumes/LaCie_Work/_TMP/test/test2.png', 'PNG')
Result : http://i.imgur.com/ewwDdZW.png - Problem : WTF ?!
All these methods are "threadable", BUT in a thread or not, if I create a simple sphere (or whatever) in this viewport the software (Nuke again) crash. I don't know why...
I decided to try with pyOpenGl:
# pyOpenGl glReadPixel
buffer = glReadPixels(0, 0, child.width(), child.height(), GL_RGB, GL_UNSIGNED_BYTE)
image = PIL.Image.fromstring(mode="RGB", size=(child.width(),child.height()), data=buffer)
image = image.transpose(PIL.Image.FLIP_TOP_BOTTOM)
image.save( '/Volumes/LaCie_Work/_TMP/test/test.png', 'PNG')
Result : http://i.imgur.com/7oBEAgj.png - Problem : Any !! :)
But...
glReadPixels need to be called in the main thread to get the right context and that hang the software... (12 to 24 frames per second) :(
With Qt :
1) Why my QGLWidget is recognize like QWidget ? (pyside bug ?)
2) Here is a way to force grabFrameBuffer() ?
3) Can I live stream the QWidget content to a QGLWidget and grab it ?
With PyOpenGL :
4) Could I access a specific Qwidget Framebuffer from a thread ?
5) Bind the FBO in an other in a new thread ?
Any help or suggestion is very welcome!

Related

vtkXMLParser some bug issues and how to solve them

I'm currently learning based on the example from the official VTK documentation, but I'm having some issues during calling vtkXMLDataParser in the I/O example
First, I'll give you the basic sample code
def main():
colors = vtkNamedColors()
#filename = get_program_parameters()
filename = "Torso.vtp"
# Read all the data from the file
reader = vtkXMLPolyDataReader()
reader.SetFileName(filename)
reader.Update()
# Visualize
mapper = vtkPolyDataMapper()
mapper.SetInputConnection(reader.GetOutputPort())
actor = vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetColor(colors.GetColor3d('NavajoWhite'))
renderer = vtkRenderer()
renderWindow = vtkRenderWindow()
renderWindow.AddRenderer(renderer)
renderWindowInteractor = vtkRenderWindowInteractor()
renderWindowInteractor.SetRenderWindow(renderWindow)
renderer.AddActor(actor)
renderer.SetBackground(colors.GetColor3d('DarkOliveGreen'))
renderer.GetActiveCamera().Pitch(90)
renderer.GetActiveCamera().SetViewUp(0, 0, 1)
renderer.ResetCamera()
renderWindow.SetSize(600, 600)
renderWindow.Render()
renderWindow.SetWindowName('ReadPolyData')
renderWindowInteractor.Start()
Then, the example requires the user to change the filename parameter to their own file path, I put the test file (.vtp) in the root directory, of course, the code can also be indexed correctly.
But after I tried to run it, the output window did not show the corresponding picture, only the background. The output window is generated along with an error window. But I don't quite understand the cause of the error and how to fix it
enter image description hereenter image description here
The following are the error messages:
2023-01-20 00:01:06.185 ( 0.043s) [ ] vtkXMLParser.cxx:379 ERR| vtkXMLDataParser (000001C077E63030): Error parsing XML in stream at line 1, column 0, byte index 0: syntax error
2023-01-20 00:01:06.235 ( 0.093s) [ ] vtkXMLReader.cxx:521 ERR| vtkXMLPolyDataReader (000001C07A3DC8A0): Error parsing input file. ReadXMLInformation aborting.
2023-01-20 00:01:06.239 ( 0.097s) [ ] vtkExecutive.cxx:741 ERR| vtkCompositeDataPipeline (000001C077E82410): Algorithm vtkXMLPolyDataReader (000001C07A3DC8A0) returned failure for request: vtkInformation (000001C07A6B6930)
Debug: Off
Modified Time: 98
Reference Count: 1
Registered Events: (none)
Request: REQUEST_INFORMATION
FORWARD_DIRECTION: 0
ALGORITHM_AFTER_FORWARD: 1
First, what is the cause of the error and how to solve it?
Second, I have never touched the configuration of the XML file of the VTK library, I just introduced the operation of the VTK library (version 9.2), how to solve the problem of this XML file?

Python error "expected LP_SDL_Window" when trying "SDL_GetWindowID"

I'm trying to get the Window ID of the SDL window, to give to VLC so it can play the video in the window.
Being new to Python, I'm vaguely aware this has to do with variable type conversions to play nice with SDL, and using the correct python binding...
The line with the error is "win_id = SDL_GetWindowID(window)"
Here is my code;
import sys
import sdl2.ext
import vlc
import ctypes
from sdl2 import *
RESOURCES = sdl2.ext.Resources(__file__, "resources")
sdl2.ext.init()
window = sdl2.ext.Window("Hello World!", size=(640, 480))
window.show()
factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE)
sprite = factory.from_image(RESOURCES.get_path("hello.bmp"))
spriterenderer = factory.create_sprite_render_system(window)
spriterenderer.render(sprite)
vlcInstance = vlc.Instance("--no-xlib")
player = vlcInstance.media_player_new()
win_id = SDL_GetWindowID(window)
player.set_xwindow(win_id)
player.set_mrl("agro.mp4")
player.play()
processor = sdl2.ext.TestEventProcessor()
processor.run(window)
sdl2.ext.quit()
What you get with SDL_GetWindowID is SDL's internal window ID that it itself refers to in e.g. events. What you need is X11 window ID, which you can get through SDL_GetWindowWMInfo. That however requires some trickery with SDL versioning, e.g. (I'm not sure it is safe to call that in python if SDL version changes but pysdl2 is not updated):
wminfo = SDL_SysWMinfo();
SDL_GetVersion(wminfo.version);
if(SDL_GetWindowWMInfo(window.window, wminfo) == 0):
print("can't get SDL WM info");
sys.exit(1);
win_id = wminfo.info.x11.window;
Then use that win_id to feed to vlc.

Pyueye image saving with wrong resolution

personally pretty new to programming and I am trying to save a high mp Image from an IDS camera using the pyueye module with python.
my Code works to save the Image, but the Problem is it saves the Image as a 1280x720 Image inside a 4192x3104
I have no idea why its saving the small Image inside the larger file and am asking if anyone knows what i am doing wrong and how can I fix it so the Image is the whole 4192x3104
from pyueye import ueye
import ctypes
hcam = ueye.HIDS(0)
pccmem = ueye.c_mem_p()
memID = ueye.c_int()
hWnd = ctypes.c_voidp()
ueye.is_InitCamera(hcam, hWnd)
ueye.is_SetDisplayMode(hcam, 0)
sensorinfo = ueye.SENSORINFO()
ueye.is_GetSensorInfo(hcam, sensorinfo)
ueye.is_AllocImageMem(hcam, sensorinfo.nMaxWidth, sensorinfo.nMaxHeight,24, pccmem, memID)
ueye.is_SetImageMem(hcam, pccmem, memID)
ueye.is_SetDisplayPos(hcam, 100, 100)
nret = ueye.is_FreezeVideo(hcam, ueye.IS_WAIT)
print(nret)
FileParams = ueye.IMAGE_FILE_PARAMS()
FileParams.pwchFileName = "python-test-image.bmp"
FileParams.nFileType = ueye.IS_IMG_BMP
FileParams.ppcImageMem = None
FileParams.pnImageID = None
nret = ueye.is_ImageFile(hcam, ueye.IS_IMAGE_FILE_CMD_SAVE, FileParams, ueye.sizeof(FileParams))
print(nret)
ueye.is_FreeImageMem(hcam, pccmem, memID)
ueye.is_ExitCamera(hcam)
The size of the image depends on the sensor size of the camera.By printing sensorinfo.nMaxWidth and sensorinfo.nMaxHeight you will get the maximum size of the image which the camera captures. I think that it depends on the model of the camera. For me it is 2056x1542.
Could you please elaborate on the last sentence of the question.

Python scapy Beacon Frames

I'm trying to build a scapy program that scans for Beacon Frames. Every router should send beacon frames to the air in an interval of X milliseconds so the possible hosts know the router(AP) is alive.
I'm getting nothing, the only kind of Dot11 frames I've been able to get so far is Prob Request, very rarely some data or control frames as well. I setup my wireless card to monitor mode before running the script and it supports it as well. I don't what I might be doing wrong... Here's the code :
from scapy.all import *
global list_prob
list_prob = []
def search_prob(packet1):
if (packet1.haslayer(Dot11)) and (packet1[Dot11].type == 0) and\
(packet1[Dot11].subtype == 8) : #type 4 == ProbRequest
if packet1[Dot11].addr2 not in list_prob:
if packet1[Dot11].info not in list_prob:
print('[>]AP',packet1[Dot11].addr2,'SSID',packet1[Dot11].info)
list_prob.append(packet1[Dot11].addr2)
list_prob.append(packet1[Dot11].info)
sniff(iface='wlan0mon',prn=search_prob)
Ive also tried it with Dot11Beacon instead of subtype 8 and nothing changed . I'm programming with python3.5 on Linux.
Any ideas ?
Code to constantly change channel of network interface using python :
from threading import Thread
import subprocess,shlex,time
import threading
locky = threading.Lock()
def Change_Freq_channel(channel_c):
print('Channel:',str(channel_c))
command = 'iwconfig wlan1mon channel '+str(channel_c)
command = shlex.split(command)
subprocess.Popen(command,shell=False) # To prevent shell injection attacks !
while True:
for channel_c in range(1,15):
t = Thread(target=Change_Freq_channel,args=(channel_c,))
t.daemon = True
locky.acquire()
t.start()
time.sleep(0.1)
locky.release()

pyside qdialog box or qaction icon is closing app

The issue is a combination of setting an icon on the action in the toolbar (or qpushbutton) and showing a qmessagebox when triggered. If I remove the icon, the message box displays. And if I remove the message box but keep the icon, the app stays open. The other odd thing is, if I add the icon to the push button but not the action, and click on the action, it still closes the app. The doubly odd thing is if I add main.qpush_button_clicked before qapplication.exec_(), the message box is displayed. However, the next time I click on either, it closes the app.
I have looked at multiple posts and some of the ideas were to use setQuitOnLastWindowClosed, but that did not fix the issue. I also implemented event to see what was happening. When I click on either of the items, it triggers a ChildAdded event, then closes.
Also, this only does not work when I use cx_Freeze on a Mac. I have not tried on Win. It works properly when run using Eclipse or from CLI.
Does anyone have any ideas on what might be causing this, or how to fix it besides not using icons.
The icon I used is from Android icon pack.
I can add the crash log if you need it.
class Main(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.qicon = QIcon('../ic_add_black_24dp_1x.png')
self.tool_bar = self.addToolBar('main')
qaction = QAction(self)
self.tool_bar.addAction(qaction)
qaction.setText('add')
qaction.setIcon(self.qicon)
qaction.triggered.connect(self.qpush_button_clicked)
qpush_button = QPushButton('add')
self.setCentralWidget(qpush_button)
qpush_button.setIcon(self.qicon)
qpush_button.clicked.connect(self.qpush_button_clicked)
def qpush_button_clicked(self, *args, **kwargs):
QMessageBox.critical(self, 'test', 'testing')
if __name__ == '__main__':
qapplication = QApplication(sys.argv)
main = Main()
main.show()
main.raise_()
qapplication.exec_()
And here is the setup file
name = 'dialog'
version = '0.1'
description = 'description'
packages = ('os',)
excludes = ('tkinter',)
include_files = ('ic_add_black_24dp_1x.png',)
build_exe = dict(packages=packages,
excludes=excludes,
include_files=include_files)
options = dict(build_exe=build_exe)
base = 'Win32GUI' if sys.platform == 'win32' else None
script = 'dialog.py'
executables = (Executable(script, base=base),)
setup(name=name,
version=version,
description=description,
options=options,
executables=executables)
PySide Version : 1.2.2
PySide Component: : (1, 2, 2, 'final', 0)
PySide Compiled Qt : 4.8.7
PySide Qt Component: (4, 8, 7)
Running Qt Version : 4.8.7

Resources