I am beating my head against a wall trying to figure out how to resize and rearrange the camera app I am building on Raspberry Pi. I want to be able to resize the window by tapping on the video, from a full-screen app to a smaller version that will display in the corner of my touch screen.
https://github.com/eighty2fifty1/multicam
I'm using OpenCV to run the camera itself. While the point of the app is to run 4 cameras and switch between them, that all happens in external hardware, so just think of it as displaying one USB webcam. I'm not completely set on using OpenCV for this, but it's worked so far.
I also seem to get segmentation faults on my RPi 4 when I try to adjust the size, minimize, or maximize the window. Not sure if that's related, but I've tried it using two brand new SD cards hoping to rule out a hardware problem.
What I've tried:
Programatically rearranging the window. Won't display video and also gives me a segmentation fault.
Subclassing MyWindowClass into BigWindowClass and SmallWindowClass, then sending the separate .ui files to their respective classes, then using the .show() and .hide() methods to determine which one I want displayed. This will show the video in the big window, but not the small one.
I left out a few of my functions for clarity's sake, but the full source code is in the github link above.
class Thread(QThread):
global file, big, small
changePixmap = pyqtSignal(QImage)
def run(self):
cap = cv2.VideoCapture(0)
while running:
ret, frame = cap.read()
if ret:
# not sure if the queue was necessary to prevent memory or processor problems
if q.qsize() < 10:
q.put(frame)
else:
print(q.qsize())
if not q.empty():
f = q.get()
rgbImage = cv2.cvtColor(f, cv2.COLOR_BGR2RGB)
h, w, ch = rgbImage.shape
bytesPerLine = ch * w
convertToQtFormat = QImage(rgbImage.data, w, h, bytesPerLine, QImage.Format_RGB888)
if file == big:
p = convertToQtFormat.scaled(640, 480, Qt.KeepAspectRatio)
elif file == small:
p = convertToQtFormat.scaled(200, 150, Qt.KeepAspectRatio)
else:
pass
self.changePixmap.emit(p)
if self.isFinished():
print("thread killed")
class MyWindowClass(QMainWindow, form_class):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self.setupUi(self)
self.sel = Selector()
self.press = 0
self.rel = 0
self.videoLbl = ClickableLabel(self.videoLbl)
self.setWindowTitle('Camera')
self.connectSignals()
self.th = Thread(self)
self.th.changePixmap.connect(self.setImage)
self.th.start()
self.show()
@pyqtSlot(QImage)
def setImage(self, image):
pixmap = QPixmap.fromImage(image)
self.videoLbl.setPixmap(pixmap)
# this will eventually be the function to change views
def _resize(self):
print("resize clicked")
# signal connections
def connectSignals(self):
self.cam1.clicked.connect(lambda: self.sel.selectCamera(1))
self.cam2.clicked.connect(lambda: self.sel.selectCamera(2))
self.cam3.clicked.connect(lambda: self.sel.selectCamera(3))
self.cam4.clicked.connect(lambda: self.sel.selectCamera(4))
self.buttonGroup.setId(self.cam1, 1)
self.buttonGroup.setId(self.cam2, 2)
self.buttonGroup.setId(self.cam3, 3)
self.buttonGroup.setId(self.cam4, 4)
'''
self.resizeButton.clicked.connect(resizeWindow)
self.posCheck.clicked.connect(posit)
'''
self.pairButton.pressed.connect(self.prPress)
self.pairButton.released.connect(self.prRel)
self.sel.camSelected.connect(self.selected)
self.videoLbl.clicked.connect(self._resize)
app = QtWidgets.QApplication(sys.argv)
window = MyWindowClass(None)
window.show()
running = True
app.exec_()