Skip to content

Commit ca5c06f

Browse files
committed
Basic tests for PyQt6 and PySide6 support
Signed-off-by: David Plowman <[email protected]>
1 parent 81a86d9 commit ca5c06f

File tree

3 files changed

+178
-0
lines changed

3 files changed

+178
-0
lines changed

tests/app_test_pyqt6.py

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/usr/bin/python3
2+
3+
# Start a Qt application, and use an asynchronous thread to "click" on the GUI.
4+
# As app_test.py, but using PyQt6 instead of PyQt5.
5+
6+
import threading
7+
import time
8+
9+
from PyQt6 import QtCore
10+
from PyQt6.QtWidgets import (QApplication, QHBoxLayout, QLabel, QPushButton,
11+
QVBoxLayout, QWidget)
12+
13+
from picamera2 import Picamera2
14+
from picamera2.previews.qt import QGl6Picamera2 as QGlPicamera2
15+
16+
17+
def post_callback(request):
18+
label.setText(''.join(f"{k}: {v}\n" for k, v in request.get_metadata().items()))
19+
20+
21+
Picamera2.set_logging()
22+
picam2 = Picamera2()
23+
picam2.post_callback = post_callback
24+
picam2.configure(picam2.create_preview_configuration(main={"size": (800, 600)}))
25+
26+
app = QApplication([])
27+
quit = False
28+
29+
30+
def on_button_clicked():
31+
button.setEnabled(False)
32+
cfg = picam2.create_still_configuration()
33+
picam2.switch_mode_and_capture_file(cfg, "test.jpg", signal_function=qpicamera2.signal_done)
34+
35+
36+
def capture_done(job):
37+
picam2.wait(job)
38+
button.setEnabled(True)
39+
40+
41+
def app_quit():
42+
if quit:
43+
app.quit()
44+
45+
46+
qpicamera2 = QGlPicamera2(picam2, width=800, height=600, keep_ar=False)
47+
button = QPushButton("Click to capture JPEG")
48+
label = QLabel()
49+
window = QWidget()
50+
qpicamera2.done_signal.connect(capture_done)
51+
button.clicked.connect(on_button_clicked)
52+
53+
label.setFixedWidth(400)
54+
label.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
55+
layout_h = QHBoxLayout()
56+
layout_v = QVBoxLayout()
57+
layout_v.addWidget(label)
58+
layout_v.addWidget(button)
59+
layout_h.addWidget(qpicamera2, 80)
60+
layout_h.addLayout(layout_v, 20)
61+
window.setWindowTitle("Qt Picamera2 App")
62+
window.resize(1200, 600)
63+
window.setLayout(layout_h)
64+
# Use timer as a hacky way to quit.
65+
timer = QtCore.QTimer()
66+
timer.timeout.connect(app_quit)
67+
timer.start(500)
68+
69+
picam2.start()
70+
window.show()
71+
72+
73+
def test_func():
74+
global quit
75+
# This function can run in another thread and "click" on the GUI.
76+
time.sleep(5)
77+
button.clicked.emit()
78+
time.sleep(5)
79+
button.clicked.emit()
80+
time.sleep(5)
81+
# A rather nasty way of quitting. We can't call app.quit() from here in PyQt6.
82+
quit = True
83+
84+
85+
thread = threading.Thread(target=test_func, daemon=True)
86+
thread.start()
87+
88+
app.exec()

tests/app_test_pyside6.py

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/usr/bin/python3
2+
3+
# Start a Qt application, and use an asynchronous thread to "click" on the GUI.
4+
# As app_test.py, but using PySide6 instead of PyQt5.
5+
6+
import threading
7+
import time
8+
9+
from PySide6 import QtCore
10+
from PySide6.QtWidgets import (QApplication, QHBoxLayout, QLabel, QPushButton,
11+
QVBoxLayout, QWidget)
12+
13+
from picamera2 import Picamera2
14+
from picamera2.previews.qt import QGlSide6Picamera2 as QGlPicamera2
15+
16+
17+
def post_callback(request):
18+
label.setText(''.join(f"{k}: {v}\n" for k, v in request.get_metadata().items()))
19+
20+
21+
Picamera2.set_logging()
22+
picam2 = Picamera2()
23+
picam2.post_callback = post_callback
24+
picam2.configure(picam2.create_preview_configuration(main={"size": (800, 600)}))
25+
26+
app = QApplication([])
27+
quit = False
28+
29+
30+
def on_button_clicked():
31+
button.setEnabled(False)
32+
cfg = picam2.create_still_configuration()
33+
picam2.switch_mode_and_capture_file(cfg, "test.jpg", signal_function=qpicamera2.signal_done)
34+
35+
36+
def capture_done(job):
37+
picam2.wait(job)
38+
button.setEnabled(True)
39+
40+
41+
def app_quit():
42+
if quit:
43+
app.quit()
44+
45+
46+
qpicamera2 = QGlPicamera2(picam2, width=800, height=600, keep_ar=False)
47+
button = QPushButton("Click to capture JPEG")
48+
label = QLabel()
49+
window = QWidget()
50+
qpicamera2.done_signal.connect(capture_done)
51+
button.clicked.connect(on_button_clicked)
52+
53+
label.setFixedWidth(400)
54+
label.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
55+
layout_h = QHBoxLayout()
56+
layout_v = QVBoxLayout()
57+
layout_v.addWidget(label)
58+
layout_v.addWidget(button)
59+
layout_h.addWidget(qpicamera2, 80)
60+
layout_h.addLayout(layout_v, 20)
61+
window.setWindowTitle("Qt Picamera2 App")
62+
window.resize(1200, 600)
63+
window.setLayout(layout_h)
64+
# Use timer as a hacky way to quit.
65+
timer = QtCore.QTimer()
66+
timer.timeout.connect(app_quit)
67+
timer.start(500)
68+
69+
picam2.start()
70+
window.show()
71+
72+
73+
def test_func():
74+
global quit
75+
# This function can run in another thread and "click" on the GUI.
76+
time.sleep(5)
77+
button.clicked.emit()
78+
time.sleep(5)
79+
button.clicked.emit()
80+
time.sleep(5)
81+
# A rather nasty way of quitting. We can't call app.quit() from here in PySide6.
82+
quit = True
83+
84+
85+
thread = threading.Thread(target=test_func, daemon=True)
86+
thread.start()
87+
88+
app.exec()

tests/test_list.txt

+2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ tests/alignment.py
5555
tests/app_dual.py
5656
tests/app_full_test.py
5757
tests/app_test.py
58+
tests/app_test_pyqt6.py
59+
tests/app_test_pyside6.py
5860
tests/autofocus_test.py
5961
tests/async_test.py
6062
tests/bitrate_check.py

0 commit comments

Comments
 (0)