Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PyQt5 shows white border while displaying image in full screen #81

Open
ammar3010 opened this issue Jul 3, 2024 · 0 comments
Open

PyQt5 shows white border while displaying image in full screen #81

ammar3010 opened this issue Jul 3, 2024 · 0 comments

Comments

@ammar3010
Copy link

I'm using PyQt5 to build a UI for my computer vision app. The app has six pages, and on the fourth page, I receive video frames from a backend thread that runs when the app reaches this page. However, I'm having trouble getting the QLabel on the fourth page to resize correctly and display the video frames in full screen.

Here is the code snippet that sends frames to the frontend:

qImg = QImage(combined_frame2.data, combined_frame2.shape[1], combined_frame2.shape[0], QImage.Format_RGB888)
self.update_video_frame.emit(qImg.rgbSwapped())

Here is the class for the fourth page:

class FourthPage(QWidget):
    recording_finished = pyqtSignal()
    switch_to_fifth_page = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self.initUI()

    def initUI(self):
        self.setContentsMargins(0, 0, 0, 0)

        # Set up the video label to take up the entire space
        self.video_label = QLabel(self)
        self.video_label.setAlignment(Qt.AlignCenter)
        self.video_label.setStyleSheet("background-color: transparent;")  # Optional: Set transparent background

        # Set video_label to cover the entire widget
        self.video_label.setGeometry(0, 0, self.width(), self.height())

        self.click_player = QMediaPlayer()

        # Install event filter to detect clicks on the video label
        self.video_label.installEventFilter(self)

    def resizeEvent(self, event):
        # Ensure video_label resizes with the widget
        self.video_label.setGeometry(0, 0, self.width(), self.height())

    def stopRecording(self):
        self.recording_finished.emit()

    def playClickSound(self):
        self.click_player.setMedia(QMediaContent(QUrl.fromLocalFile("/path/to/Click.mp3")))
        self.click_player.setVolume(100)
        self.click_player.play()
    
    def handleMouseClick(self):
        self.stopRecording()
        self.playClickSound()
        QTimer.singleShot(500, self.switch_to_fifth_page.emit)

    def eventFilter(self, source, event):
        if event.type() == QEvent.MouseButtonPress and source == self.video_label:
            self.handleMouseClick()
            return True
        return super().eventFilter(source, event)

Here is the main class that controls the flow of the app:

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.stack = QStackedWidget(self)
        self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
        self.setGeometry(0, 0, 800, 600)
        self.showFullScreen()
        self.initUI()

    def initUI(self):
        layout = QVBoxLayout(self)
        self.introPage = IntroPage()
        self.firstPage = FirstPage()
        self.secondPage = SecondPage()
        self.thirdPage = ThirdPage()
        self.fourthPage = FourthPage()
        self.startRecordingPage = StartRecordingPage()
        self.fifthPage = FifthPage()
        self.sixthPage = SixthPage()
        self.stack.addWidget(self.introPage)
        self.stack.addWidget(self.firstPage)
        self.stack.addWidget(self.secondPage)
        self.stack.addWidget(self.thirdPage)
        self.stack.addWidget(self.startRecordingPage)
        self.stack.addWidget(self.fourthPage)
        self.stack.addWidget(self.fifthPage)
        self.stack.addWidget(self.sixthPage)
        layout.addWidget(self.stack)
        self.setLayout(layout)

        self.introPage.switch_to_first_page.connect(self.showFirstPage)
        self.firstPage.switch_to_second_page.connect(self.showSecondPage)
        self.secondPage.switch_to_third_page.connect(self.showThirdPage)
        self.thirdPage.switch_to_recording_page.connect(self.showStartRecordingPage)
        self.startRecordingPage.switch_to_fourth_page.connect(self.showFourthPage)
        self.fourthPage.switch_to_fifth_page.connect(self.showFifthPage)
        self.fourthPage.recording_finished.connect(self.stopRecording)
        self.sixthPage.restart_requested.connect(self.restartApp)
        self.sixthPage.exit_requested.connect(self.exitApp)

        self.backend_thread = BackendThread()
        self.backend_thread.update_video_frame.connect(self.update_video_frame)
        self.backend_thread.finished.connect(self.showSixthPage)
        self.showFullScreen()

    def stopRecording(self):
        self.backend_thread.stop_recording = True

    def showFirstPage(self):
        self.stack.setCurrentWidget(self.firstPage)

    def showSecondPage(self):
        self.stack.setCurrentWidget(self.secondPage)

    def showThirdPage(self):
        self.stack.setCurrentWidget(self.thirdPage)

    def showStartRecordingPage(self):
        self.stack.setCurrentWidget(self.startRecordingPage)

    def showFourthPage(self):
        self.stack.setCurrentWidget(self.fourthPage)
        self.backend_thread.start()

    def showFifthPage(self):
        self.stack.setCurrentWidget(self.fifthPage)
        QTimer.singleShot(100, self.run_processing)  # Delay the processing to allow the UI to update

    def showSixthPage(self):
        self.stack.setCurrentWidget(self.sixthPage)
        self.display_results()

    def run_processing(self):
        self.backend_thread.run_processing()

    def update_video_frame(self, qImg):
        self.fourthPage.video_label.setPixmap(QPixmap.fromImage(qImg))

    def display_results(self):
        font = self.sixthPage.results_label.font()
        font.setPointSize(14)
        self.sixthPage.results_label.setFont(font)
        self.sixthPage.results_label.setWordWrap(True)
        self.sixthPage.results_label.setFixedWidth(self.width() - 20)
        self.sixthPage.results_label.setText(
            f"Frame count: {self.backend_thread.frame_count}\n"
            f"FPS: {self.backend_thread.fps}\n"
            f"Transcript: {self.backend_thread.transcript}\n"
            f"Objects List: {self.backend_thread.objects_list}\n"
            f"Phrase Timestamps: {self.backend_thread.phrase_timestamps}\n"
        )

    def restartApp(self):
        self.stack.setCurrentWidget(self.introPage)

    def exitApp(self):
        QApplication.instance().quit()

Problem: The QLabel on the fourth page does not resize correctly to display the video frames in full screen. I've tried different spacing and margin options, but none of them work. It gives white borders on left, right and top

Question: How can I ensure that the QLabel resizes correctly and displays the video frames in full screen on the fourth page?

Any help or suggestions would be greatly appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant