Hello,Hi, yes I saw this message but didn't reply because I'm sure there are folks out there who know way more about Qt than I do! (TBH, it's a low bar...)I'm bringing this post up because I saw that Therealdavidp was around... Image may be NSFW.
Clik here to view.
So far as I understand things, the QThreadPool provides very similar functionality, but of course integrates more nicely if you want to pass data or messages back into your main Qt thread. Though if you simply have a "start" button which launches loads of threads, and a "stop" button which waits for your thread pool to finish, then I guess I don't see a great deal of benefit (so long as waiting for everything to finish doesn't take forever and lock up your GUI in the meantime). Sorry not to be more help - I'm still hoping there might be some "real" Qt programmers out there!!
I finally managed to write a script that no longer uses the ThreadPoolExecutor but the QThreadPool.
It works very well even when displaying a Preview.QTGL preview window, I get a stable framerate.
Code:
from PyQt5.QtCore import QRunnable, QThreadPoolfrom picamera2 import Picamera2, Previewclass SaveDNGTask(QRunnable): def __init__(self, picam2, i, metadata, raw_im): super().__init__() self.picam2 = picam2 self.i = i self.metadata = metadata self.raw_im = raw_im def run(self): self.picam2.helpers.save_dng(self.raw_im, self.metadata, config['raw'], f"image_{self.i:04}.dng")# Création du thread poolthread_pool = QThreadPool()thread_pool.setMaxThreadCount(4)picam2 = Picamera2()picam2.start_preview(Preview.QTGL)raw = {'size': (2028, 1520), 'format': 'SBGGR12'}config = picam2.create_video_configuration({'size': (640, 360)}, raw=raw)picam2.configure(config)picam2.start()for i in range(10): request = picam2.capture_request() task = SaveDNGTask(picam2, i, request.get_metadata(), request.make_buffer('raw')) thread_pool.start(task) request.release()thread_pool.waitForDone()
The preview freezes and the .dng files don't save.
There seems to be a problem with picam2.capture_request and self.qpicamera2 = QGlPicamera2(picam2)
Code:
import sysfrom PyQt5 import QtGuifrom PyQt5.QtCore import *from PyQt5.QtWidgets import *from PyQt5 import QtCorefrom PyQt5.QtCore import QRunnable, QThreadPoolfrom PyQt5 import QtWidgetsfrom PyQt5.QtWidgets import QPushButton, QVBoxLayoutfrom PyQt5.QtGui import QPalette, QColorfrom picamera2.previews.qt import QGlPicamera2from picamera2.encoders import H264Encoder, Qualityfrom picamera2.outputs import FfmpegOutput from picamera2 import Picamera2, Preview, MappedArrayfrom libcamera import Transform, controlsapp= QApplication(sys.argv)picam2 = Picamera2()class SaveDNGTask(QRunnable): def __init__(self, picam2, i, metadata, raw_im): super().__init__() self.picam2 = picam2 self.i = i self.metadata = metadata self.raw_im = raw_im def run(self): self.picam2.helpers.save_dng(self.raw_im, self.metadata, config['raw'], f"image_{self.i:04}.dng")class MainWindow(QMainWindow): def __init__(self,*args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.preview = QWidget() self.setCentralWidget(self.preview) self.vLayout = QVBoxLayout(self.centralWidget()) thread_pool = QThreadPool() thread_pool.setMaxThreadCount(4) self.qpicamera2 = QGlPicamera2(picam2) self.vLayout.addWidget(self.qpicamera2) raw = {'size': (2028, 1520), 'format': 'SBGGR12'} config = picam2.create_video_configuration({'size': (800, 600)}, raw=raw) picam2.configure(config) picam2.start() def keyPressEvent(self, event): if event.key() == Qt.Key_Space: for i in range(10): request = picam2.capture_request() task = SaveDNGTask(picam2, i, request.get_metadata(), request.make_buffer('raw')) thread_pool.start(task) request.release() thread_pool.waitForDone() else: thread_pool.waitForDone()window = MainWindow()window.setStyleSheet("background-color: black;")window.setWindowTitle("Camera")window.show()app.exec_()
Thank you.
Statistics: Posted by davebixby — Thu Apr 18, 2024 9:04 am