#pragma once #include #include #include #include #include #include #include #include #include #include "v4l2worker.h" // VideoWidget shows a live preview of a V4L2 capture device. // It lives in the right-side panel, below the Tag Monitor. // Features: // - Device selector (auto-enumerates /dev/video*) // - Start / Stop capture // - Freeze-frame toggle // - Screenshot (saves current frame as PNG/JPG) // - Frame is scaled to fit the widget while keeping aspect ratio class VideoWidget : public QWidget { Q_OBJECT public: explicit VideoWidget(QWidget *parent = nullptr); ~VideoWidget(); public: // Called by MainWindow::closeEvent to guarantee orderly shutdown before // widget destruction. Safe to call multiple times. void shutdown(); public slots: void onNewFrame(const QImage &frame); private slots: void onStartStop(); void onFreeze(bool frozen); void onScreenshot(); void refreshDeviceList(); protected: void paintEvent(QPaintEvent *event) override; void resizeEvent(QResizeEvent *event) override; private: void setupUi(); void startCapture(); void stopCapture(); void updateScaled(); // Worker QThread *m_thread = nullptr; V4l2Worker *m_worker = nullptr; // Current frame QImage m_frame; QImage m_scaled; bool m_frozen = false; bool m_running = false; bool m_shutdownDone = false; // UI QComboBox *m_deviceCombo = nullptr; QPushButton *m_startBtn = nullptr; QPushButton *m_freezeBtn = nullptr; QPushButton *m_screenshotBtn= nullptr; QLabel *m_infoLabel = nullptr; };