Python/PyQt5 GUI to control Raspberry Pi Camera using picamera2 lib
Previous post show a simple example of Using the Raspberry Pi Camera in Python3/PyQt5 applications using picamera2
lib, here is another exercise with more.
The video show the
Python/PyQt5 run on
Raspberry Pi 5 with dual camera, Camera Module 3 & HQ Camera with 6mm
3MP lens. The Raspberry Pi 5 is running 64-bit Raspberry Pi OS (bookworm).
Note that if picam2 = Picamera(0) to use HQ Camera, the code will report
RuntimeError: Control AfMode is not advertised by libcamera. Because HQ Camera have no Auto-Focus function.
picam2_qt5_2023-12-28.py
"""
Python 3/PyQt5 + picamera2 to control Raspberry Pi Camera Modules
Tested on Raspberry Pi 5/64-bit Raspberry Pi OS (bookworm)
# in my setup:
# Picamera2(0) - HQ Camera
# Picamera2(1) - Camera Module 3
"""
import sys, platform, os
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QLabel, QWidget, QTabWidget, QVBoxLayout, QGridLayout
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot, Qt
from PyQt5.QtGui import QPalette, QColor, QFont
from picamera2 import Picamera2
from picamera2.previews.qt import QGlPicamera2
from picamera2 import __name__ as picamera2_name
from libcamera import controls
import time
from importlib.metadata import version
os.environ["LIBCAMERA_LOG_LEVELS"] = "3"
picam2 = Picamera2(1)
#=====================================
preview_width= 800
preview_height = int(picam2.sensor_resolution[1] * preview_width/picam2.sensor_resolution[0])
preview_config_raw = picam2.create_preview_configuration(main={"size": (preview_width, preview_height)},
raw={"size": picam2.sensor_resolution})
picam2.configure(preview_config_raw)
#=====================================
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
#=====================================
class App(QMainWindow):
def __init__(self):
super().__init__()
self.title = __file__
self.left = 0
self.top = 0
self.setWindowTitle(self.title)
self.main_widget = MyMainWidget(self)
self.setCentralWidget(self.main_widget)
self.show()
class MyMainWidget(QWidget):
def read_f(self, file):
with open(file, encoding='UTF-8') as reader:
content = reader.read()
return content
def read_pretty_name(self):
with open("/etc/os-release") as f:
os_release = {}
for line in f:
k,v = line.rstrip().split("=")
os_release[k] = v.strip('"')
return os_release['PRETTY_NAME']
def on_Capture_Clicked(self):
global picam2
self.btnCapture.setEnabled(False)
cfg = picam2.create_still_configuration()
timeStamp = time.strftime("%Y%m%d-%H%M%S")
targetPath="/home/pi/Desktop/img_"+timeStamp+".jpg"
print("- Capture image:", targetPath)
picam2.switch_mode_and_capture_file(cfg, targetPath,signal_function=self.qpicamera2.signal_done)
def capture_done(self, job):
global picam2
result = picam2.wait(job)
self.btnCapture.setEnabled(True)
print("- capture_done.")
def __init__(self, parent):
super(QWidget, self).__init__(parent)
self.layout = QVBoxLayout()
# Initialize tab screen
self.tabs = QTabWidget()
self.tabCapture = QWidget()
self.tabInfo = QWidget()
# Add tabs
self.tabs.addTab(self.tabCapture,"Capture")
self.tabs.addTab(self.tabInfo," Info ")
#=== Tab Capture ===
# Create first tab
self.tabCapture.layout = QVBoxLayout()
self.tabCapture.setAutoFillBackground(True)
palette = self.palette()
palette.setColor(QPalette.Window, QColor('black'))
self.tabCapture.setPalette(palette)
#Prepare Preview
self.qpicamera2 = QGlPicamera2(picam2,
width=preview_width, height=preview_height,
keep_ar=True)
self.tabCapture.layout.addWidget(self.qpicamera2)
self.qpicamera2.done_signal.connect(self.capture_done)
self.btnCapture = QPushButton("Capture Image")
self.btnCapture.setFont(QFont("Helvetica", 20, QFont.Bold))
self.btnCapture.clicked.connect(self.on_Capture_Clicked)
self.tabCapture.layout.addWidget(self.btnCapture)
#self.tabCapture.layout.addStretch()
self.tabCapture.setLayout(self.tabCapture.layout)
#=== Tab Info ===
self.tabInfo.layout = QVBoxLayout()
infoGridLayout = QGridLayout()
rowSpan = 1
columnSpan0 = 1
columnSpan1 = 5
infoGridLayout.addWidget(QLabel('Python', self), 0, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(platform.python_version(), self), 0, 1, rowSpan, columnSpan1)
infoGridLayout.addWidget(QLabel(picamera2_name, self), 1, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(version(picamera2_name), self), 1, 1, rowSpan, columnSpan1)
infoGridLayout.addWidget(QLabel(' ', self), 2, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('Camera Module:', self), 3, 0, rowSpan, columnSpan0)
cam_properties = picam2.camera_properties
cam_Model = cam_properties['Model']
infoGridLayout.addWidget(QLabel('Model', self), 4, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(cam_Model, self), 4, 1, rowSpan, columnSpan1)
cam_PixelArraySize = str(cam_properties['PixelArraySize'][0]) + " x " + str(cam_properties['PixelArraySize'][1])
infoGridLayout.addWidget(QLabel('PixelArraySize', self), 5, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(cam_PixelArraySize, self), 5, 1, rowSpan, columnSpan1)
infoGridLayout.addWidget(QLabel(' ', self), 6, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('Machine:', self), 7, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('Board', self), 8, 0, rowSpan, columnSpan0, Qt.AlignTop)
board_def = "/proc/device-tree/model"
board_info = self.read_f("/proc/device-tree/model") +"\n(" + board_def +")"
infoGridLayout.addWidget(QLabel(board_info, self), 8, 1, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('OS', self), 9, 0, rowSpan, columnSpan0, Qt.AlignTop)
os_info = self.read_pretty_name() + "\n" + os.uname()[3]
infoGridLayout.addWidget(QLabel(os_info, self), 9, 1, rowSpan, columnSpan1)
self.tabInfo.layout.addLayout(infoGridLayout)
self.tabInfo.layout.addStretch()
self.tabInfo.setLayout(self.tabInfo.layout)
#==================================
# Add tabs to widget
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
picam2.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
by Camera Module 3:
by HQ Camera with 6mm 3MP lens:
Added@2024-01-03
Below add function to detect Auto-Focus feature and switching AF Mode between
Continuous & Manual.
To detect Auto-Focus feature in the camera attached, call picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous}) inside a try...except... block. Then, enable/disable the QCheckBox of Auto-Focus Mode accordingly.
To detect Auto-Focus feature in the camera attached, call picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous}) inside a try...except... block. Then, enable/disable the QCheckBox of Auto-Focus Mode accordingly.
#Detect if AF function is available
AF_Function = True
AF_Enable = True
try:
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
print("Auto-Focus Function Enabled")
except RuntimeError as err:
print("RuntimeError:", err)
AF_Function = False
Updated code, picam2_qt5_2024-01-03.py.
"""
Python 3/PyQt5 + picamera2 to control Raspberry Pi Camera Modules
Tested on Raspberry Pi 5/64-bit Raspberry Pi OS (bookworm)
# in my setup:
# Picamera2(0) - HQ Camera
# Picamera2(1) - Camera Module 3
picam2_qt5_2023-12-28.py first exercise
picam2_qt5_2024-01-03.py Added Auto-Focus feature detection, and switch AF Mode between Continuous & Manual
"""
import sys, platform, os
from PyQt5.QtWidgets import (QMainWindow, QApplication, QPushButton, QLabel, QCheckBox,
QWidget, QTabWidget, QVBoxLayout, QGridLayout)
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot, Qt
from PyQt5.QtGui import QPalette, QColor, QFont
from picamera2 import Picamera2
from picamera2.previews.qt import QGlPicamera2
from picamera2 import __name__ as picamera2_name
from libcamera import controls
import time
from importlib.metadata import version
os.environ["LIBCAMERA_LOG_LEVELS"] = "3"
picam2 = Picamera2(0)
#=====================================
preview_width= 800
preview_height = int(picam2.sensor_resolution[1] * preview_width/picam2.sensor_resolution[0])
preview_config_raw = picam2.create_preview_configuration(main={"size": (preview_width, preview_height)},
raw={"size": picam2.sensor_resolution})
picam2.configure(preview_config_raw)
#=====================================
#Detect if AF function is available
AF_Function = True
AF_Enable = True
try:
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
print("Auto-Focus Function Enabled")
except RuntimeError as err:
print("RuntimeError:", err)
AF_Function = False
#=====================================
class App(QMainWindow):
def __init__(self):
super().__init__()
self.title = __file__
self.left = 0
self.top = 0
self.setWindowTitle(self.title)
self.main_widget = MyMainWidget(self)
self.setCentralWidget(self.main_widget)
self.show()
class MyMainWidget(QWidget):
def read_f(self, file):
with open(file, encoding='UTF-8') as reader:
content = reader.read()
return content
def read_pretty_name(self):
with open("/etc/os-release") as f:
os_release = {}
for line in f:
k,v = line.rstrip().split("=")
os_release[k] = v.strip('"')
return os_release['PRETTY_NAME']
def AF_Enable_CheckBox_onStateChanged(self):
if self.AF_Enable_CheckBox.isChecked():
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
else:
picam2.set_controls({"AfMode": controls.AfModeEnum.Manual})
@pyqtSlot()
def on_Capture_Clicked(self):
global picam2
self.btnCapture.setEnabled(False)
cfg = picam2.create_still_configuration()
timeStamp = time.strftime("%Y%m%d-%H%M%S")
targetPath="/home/pi/Desktop/img_"+timeStamp+".jpg"
print("- Capture image:", targetPath)
picam2.switch_mode_and_capture_file(cfg, targetPath, signal_function=self.qpicamera2.signal_done)
def capture_done(self, job):
global picam2
result = picam2.wait(job)
self.btnCapture.setEnabled(True)
print("- capture_done.")
def __init__(self, parent):
super(QWidget, self).__init__(parent)
self.layout = QVBoxLayout()
# Initialize tab screen
self.tabs = QTabWidget()
self.tabCapture = QWidget()
self.tabInfo = QWidget()
# Add tabs
self.tabs.addTab(self.tabCapture,"Capture")
self.tabs.addTab(self.tabInfo," Info ")
#=== Tab Capture ===
# Create first tab
self.tabCapture.layout = QVBoxLayout()
"""
self.tabCapture.setAutoFillBackground(True)
palette = self.palette()
palette.setColor(QPalette.Window, QColor('black'))
self.tabCapture.setPalette(palette)
"""
#Prepare Preview
if AF_Function:
self.AF_Enable_CheckBox = QCheckBox("Auto-Focus (Continuous)")
self.AF_Enable_CheckBox.setChecked(True)
self.AF_Enable_CheckBox.setEnabled(True)
self.AF_Enable_CheckBox.stateChanged.connect(self.AF_Enable_CheckBox_onStateChanged)
else:
self.AF_Enable_CheckBox = QCheckBox("No Auto-Focus function")
self.AF_Enable_CheckBox.setChecked(False)
self.AF_Enable_CheckBox.setEnabled(False)
self.tabCapture.layout.addWidget(self.AF_Enable_CheckBox)
self.qpicamera2 = QGlPicamera2(picam2,
width=preview_width, height=preview_height,
keep_ar=True)
self.tabCapture.layout.addWidget(self.qpicamera2)
self.qpicamera2.done_signal.connect(self.capture_done)
self.btnCapture = QPushButton("Capture Image")
self.btnCapture.setFont(QFont("Helvetica", 20, QFont.Bold))
self.btnCapture.clicked.connect(self.on_Capture_Clicked)
self.tabCapture.layout.addWidget(self.btnCapture)
#self.tabCapture.layout.addStretch()
self.tabCapture.setLayout(self.tabCapture.layout)
#=== Tab Info ===
self.tabInfo.layout = QVBoxLayout()
infoGridLayout = QGridLayout()
rowSpan = 1
columnSpan0 = 1
columnSpan1 = 5
infoGridLayout.addWidget(QLabel('Python', self), 0, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(platform.python_version(), self), 0, 1, rowSpan, columnSpan1)
infoGridLayout.addWidget(QLabel(picamera2_name, self), 1, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(version(picamera2_name), self), 1, 1, rowSpan, columnSpan1)
infoGridLayout.addWidget(QLabel(' ', self), 2, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('Camera Module:', self), 3, 0, rowSpan, columnSpan0)
cam_properties = picam2.camera_properties
cam_Model = cam_properties['Model']
infoGridLayout.addWidget(QLabel('Model', self), 4, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(cam_Model, self), 4, 1, rowSpan, columnSpan1)
cam_PixelArraySize = str(cam_properties['PixelArraySize'][0]) + " x " + str(cam_properties['PixelArraySize'][1])
infoGridLayout.addWidget(QLabel('PixelArraySize', self), 5, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(cam_PixelArraySize, self), 5, 1, rowSpan, columnSpan1)
infoGridLayout.addWidget(QLabel(' ', self), 6, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('Machine:', self), 7, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('Board', self), 8, 0, rowSpan, columnSpan0, Qt.AlignTop)
board_def = "/proc/device-tree/model"
board_info = self.read_f("/proc/device-tree/model") +"\n(" + board_def +")"
infoGridLayout.addWidget(QLabel(board_info, self), 8, 1, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('OS', self), 9, 0, rowSpan, columnSpan0, Qt.AlignTop)
os_info = self.read_pretty_name() + "\n" + os.uname()[3]
infoGridLayout.addWidget(QLabel(os_info, self), 9, 1, rowSpan, columnSpan1)
self.tabInfo.layout.addLayout(infoGridLayout)
self.tabInfo.layout.addStretch()
self.tabInfo.setLayout(self.tabInfo.layout)
#==================================
# Add tabs to widget
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
picam2.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
Added@2024-01-07
Python/PyQt5/Picamera2 to control Raspberry Pi Camera with GUI (Open Preview in another window)
picam2_qt5_2024-01-07.py
"""
Python 3/PyQt5 + picamera2 to control Raspberry Pi Camera Modules
Tested on Raspberry Pi 5/64-bit Raspberry Pi OS (bookworm)
# in my setup:
# Picamera2(0) - HQ Camera
# Picamera2(1) - Camera Module 3
picam2_qt5_2023-12-28.py first exercise
picam2_qt5_2024-01-03.py Added Auto-Focus feature detection, and switch AF Mode between Continuous & Manual
picam2_qt5_2024-01-07.py Display Preview in seperated window, both Main/Preview windows have Capture button.
"""
import sys, platform, os
from PyQt5.QtWidgets import (QMainWindow, QApplication, QPushButton, QLabel, QCheckBox,
QWidget, QTabWidget, QVBoxLayout, QGridLayout)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont
from picamera2 import Picamera2
from picamera2.previews.qt import QGlPicamera2
from picamera2 import __name__ as picamera2_name
from libcamera import controls
import time
from importlib.metadata import version
os.environ["LIBCAMERA_LOG_LEVELS"] = "3"
#picam2 = Picamera2() #default to Picamera2(0) without parameter passed
picam2 = Picamera2(1)
#=====================================
preview_width= 1000
preview_height = int(picam2.sensor_resolution[1] * preview_width/picam2.sensor_resolution[0])
preview_config_raw = picam2.create_preview_configuration(main={"size": (preview_width, preview_height)},
raw={"size": picam2.sensor_resolution})
picam2.configure(preview_config_raw)
#=====================================
#Detect if AF function is available
AF_Function = True
AF_Enable = True
try:
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
print("Auto-Focus Function Enabled")
except RuntimeError as err:
print("RuntimeError:", err)
AF_Function = False
#=====================================
class App(QMainWindow):
def __init__(self):
super().__init__()
self.title = __file__
self.left = 0
self.top = 0
self.setWindowTitle(self.title)
self.main_widget = MyMainWidget(self)
self.setCentralWidget(self.main_widget)
self.show()
class MyMainWidget(QWidget):
#--- MyPreviewWidget ---
#inner class for Preview Window
class MyPreviewWidget(QWidget):
def __init__(self, subLayout):
super(QWidget, self).__init__()
self.setLayout(subLayout)
#--- End of MyPreviewWidget ---
def read_f(self, file):
with open(file, encoding='UTF-8') as reader:
content = reader.read()
return content
def read_pretty_name(self):
with open("/etc/os-release", encoding='UTF-8') as f:
os_release = {}
for line in f:
k,v = line.rstrip().split("=")
os_release[k] = v.strip('"')
return os_release['PRETTY_NAME']
def AF_Enable_CheckBox_onStateChanged(self):
if self.AF_Enable_CheckBox.isChecked():
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
else:
picam2.set_controls({"AfMode": controls.AfModeEnum.Manual})
def on_Capture_Clicked(self):
# There are two buttons on Main/Child Window connected here,
# identify the sender for info only, no actual use.
sender = self.sender()
if sender is self.btnCapture:
print("Capture button on Main Window clicked")
if sender is self.btnChildCapture:
print("Capture button on Child Preview Window clicked")
self.btnCapture.setEnabled(False)
cfg = picam2.create_still_configuration()
timeStamp = time.strftime("%Y%m%d-%H%M%S")
targetPath="/home/pi/Desktop/img_"+timeStamp+".jpg"
print("- Capture image:", targetPath)
picam2.switch_mode_and_capture_file(cfg, targetPath, signal_function=self.qpicamera2.signal_done)
def capture_done(self, job):
result = picam2.wait(job)
self.btnCapture.setEnabled(True)
print("- capture_done.")
print(result)
def __init__(self, parent):
super(QWidget, self).__init__(parent)
#--- Prepare child Preview Window ----------
self.childPreviewLayout = QVBoxLayout()
# Check Auto-Focus feature
if AF_Function:
self.AF_Enable_CheckBox = QCheckBox("Auto-Focus (Continuous)")
self.AF_Enable_CheckBox.setChecked(True)
self.AF_Enable_CheckBox.setEnabled(True)
self.AF_Enable_CheckBox.stateChanged.connect(self.AF_Enable_CheckBox_onStateChanged)
self.childPreviewLayout.addWidget(self.AF_Enable_CheckBox)
print("show Auto-Focus Mode Change QCheckBox")
else:
self.AF_Enable_CheckBox = QCheckBox("No Auto-Focus function")
self.AF_Enable_CheckBox.setChecked(False)
self.AF_Enable_CheckBox.setEnabled(False)
print("No Auto-Focus Mode Change QCheckBox")
# Preview qpicamera2
self.qpicamera2 = QGlPicamera2(picam2,
width=preview_width, height=preview_height,
keep_ar=True)
self.qpicamera2.done_signal.connect(self.capture_done)
self.childPreviewLayout.addWidget(self.qpicamera2)
# Capture button on Child Window
self.btnChildCapture = QPushButton("Capture Image")
self.btnChildCapture.setFont(QFont("Helvetica", 13, QFont.Bold))
self.btnChildCapture.clicked.connect(self.on_Capture_Clicked)
self.childPreviewLayout.addWidget(self.btnChildCapture)
# pass layout to child Preview Window
self.myPreviewWindow = self.MyPreviewWidget(self.childPreviewLayout)
# roughly set Preview windows size according to preview_width x preview_height
self.myPreviewWindow.setGeometry(10, 10, preview_width+10, preview_height+100)
self.myPreviewWindow.setWindowTitle("Preview size - " +
str(preview_width) + " x " + str(preview_height))
self.myPreviewWindow.show()
#--- End of Prepare child Preview Window ---
self.layout = QVBoxLayout()
# Initialize tab screen
self.tabs = QTabWidget()
self.tabControl = QWidget()
self.tabInfo = QWidget()
# Add tabs
self.tabs.addTab(self.tabControl,"Control")
self.tabs.addTab(self.tabInfo, " Info ")
#=== Tab Capture ===
# Create first tab
self.tabControl.layout = QVBoxLayout()
self.btnCapture = QPushButton("Capture Image")
self.btnCapture.setFont(QFont("Helvetica", 15, QFont.Bold))
self.btnCapture.clicked.connect(self.on_Capture_Clicked)
self.tabControl.layout.addWidget(self.btnCapture)
self.labelMore = QLabel("...more will place here in coming exercise.")
self.tabControl.layout.addWidget(self.labelMore)
self.tabControl.layout.addStretch()
self.tabControl.setLayout(self.tabControl.layout)
#=== Tab Info ===
self.tabInfo.layout = QVBoxLayout()
infoGridLayout = QGridLayout()
rowSpan = 1
columnSpan0 = 1
columnSpan1 = 5
infoGridLayout.addWidget(QLabel('Python', self), 0, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(platform.python_version(), self), 0, 1, rowSpan, columnSpan1)
infoGridLayout.addWidget(QLabel(picamera2_name, self), 1, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(version(picamera2_name), self), 1, 1, rowSpan, columnSpan1)
infoGridLayout.addWidget(QLabel(' ', self), 2, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('Camera Module:', self), 3, 0, rowSpan, columnSpan0)
cam_properties = picam2.camera_properties
cam_Model = cam_properties['Model']
infoGridLayout.addWidget(QLabel('Model', self), 4, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(cam_Model, self), 4, 1, rowSpan, columnSpan1)
cam_PixelArraySize = str(cam_properties['PixelArraySize'][0]) + " x " + str(cam_properties['PixelArraySize'][1])
infoGridLayout.addWidget(QLabel('PixelArraySize', self), 5, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(cam_PixelArraySize, self), 5, 1, rowSpan, columnSpan1)
infoGridLayout.addWidget(QLabel(' ', self), 6, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('Machine:', self), 7, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('Board', self), 8, 0, rowSpan, columnSpan0, Qt.AlignTop)
board_def = "/proc/device-tree/model"
board_info = self.read_f("/proc/device-tree/model") +"\n(" + board_def +")"
infoGridLayout.addWidget(QLabel(board_info, self), 8, 1, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('OS', self), 9, 0, rowSpan, columnSpan0, Qt.AlignTop)
os_info = self.read_pretty_name() + "\n" + os.uname()[3]
infoGridLayout.addWidget(QLabel(os_info, self), 9, 1, rowSpan, columnSpan1)
self.tabInfo.layout.addLayout(infoGridLayout)
self.tabInfo.layout.addStretch()
self.tabInfo.setLayout(self.tabInfo.layout)
#==================================
# Add tabs to widget
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
picam2.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
more:
~ Python/PyQt5/Picamera2 to control Raspberry Pi Cameras with GUI, with camera_controls.
~ Python/PyQt5/Picamera2 to control Raspberry Pi Cameras with GUI, added White Balance setting.
~ Python 3/PyQt5 + picamera2 on Raspberry Pi, list available cameras.
Comments
Post a Comment