Über... hinzugefügt, Icon hinzugefügt
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
#include <QMainWindow>
|
||||
#include <QCloseEvent>
|
||||
#include <QSettings>
|
||||
#include <QSplitter>
|
||||
#include <QThread>
|
||||
#include <QTabWidget>
|
||||
#include <QSplitter>
|
||||
@@ -14,6 +17,7 @@
|
||||
#include "rawview.h"
|
||||
#include "tableview.h"
|
||||
#include "tagwidget.h"
|
||||
#include "videowidget.h"
|
||||
#include "connectdialog.h"
|
||||
#include <QSet>
|
||||
|
||||
@@ -37,21 +41,29 @@ private slots:
|
||||
void onTagDetected(const QString &tag, const QString &value);
|
||||
void showFormatReference();
|
||||
void configureTagFilter();
|
||||
void showAbout();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private:
|
||||
void setupUi();
|
||||
void setupToolBar();
|
||||
void setupStatusBar();
|
||||
void clearAllViews();
|
||||
void doShutdown();
|
||||
void saveSettings();
|
||||
void restoreSettings();
|
||||
|
||||
// Worker & thread
|
||||
QThread *m_thread = nullptr;
|
||||
SerialWorker *m_worker = nullptr;
|
||||
|
||||
// Views
|
||||
RawView *m_rawView = nullptr;
|
||||
TableView *m_tableView = nullptr;
|
||||
TagWidget *m_tagWidget = nullptr;
|
||||
RawView *m_rawView = nullptr;
|
||||
TableView *m_tableView = nullptr;
|
||||
TagWidget *m_tagWidget = nullptr;
|
||||
VideoWidget *m_videoWidget= nullptr;
|
||||
|
||||
// Status bar widgets
|
||||
QLabel *m_portLabel = nullptr;
|
||||
@@ -66,6 +78,11 @@ private:
|
||||
QAction *m_connectAction = nullptr;
|
||||
QAction *m_disconnectAction = nullptr;
|
||||
|
||||
// Splitters (saved/restored via QSettings)
|
||||
QSplitter *m_mainSplitter = nullptr;
|
||||
QSplitter *m_rightSplitter = nullptr;
|
||||
|
||||
SerialConfig m_lastConfig;
|
||||
QSet<QString> m_suppressedTags; // tags hidden from Raw view
|
||||
bool m_shutdownDone = false;
|
||||
};
|
||||
|
||||
49
include/v4l2worker.h
Normal file
49
include/v4l2worker.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
#include <QObject>
|
||||
#include <QImage>
|
||||
#include <QString>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
class V4l2Worker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit V4l2Worker(QObject *parent = nullptr);
|
||||
~V4l2Worker();
|
||||
|
||||
public slots:
|
||||
void startCapture(const QString &device, int width = 1920, int height = 1080);
|
||||
void stopCapture();
|
||||
|
||||
signals:
|
||||
void newFrame(const QImage &frame);
|
||||
void captureStarted(const QString &device, int width, int height, const QString &format);
|
||||
void captureStopped();
|
||||
void errorOccurred(const QString &message);
|
||||
|
||||
private:
|
||||
void stop(); // joins m_captureThread, closes device – safe from any thread
|
||||
void captureLoop(); // runs inside m_captureThread
|
||||
bool openDevice(const QString &device, int width, int height);
|
||||
void closeDevice();
|
||||
bool initMmap();
|
||||
void freeMmap();
|
||||
QImage convertToImage(const void *data, size_t size, int width, int height);
|
||||
QImage yuyv2Rgb(const uchar *src, int width, int height);
|
||||
QImage nv122Rgb(const uchar *src, int width, int height);
|
||||
|
||||
int m_fd = -1;
|
||||
int m_width = 1920;
|
||||
int m_height = 1080;
|
||||
uint32_t m_pixFmt = 0;
|
||||
|
||||
static constexpr int MMAP_BUFFERS = 4;
|
||||
struct MmapBuffer { void *start = nullptr; size_t length = 0; };
|
||||
MmapBuffer m_buffers[MMAP_BUFFERS];
|
||||
int m_nBuffers = 0;
|
||||
|
||||
std::atomic<bool> m_running{false};
|
||||
std::thread m_captureThread; // dedicated capture thread – not the Qt event thread
|
||||
};
|
||||
71
include/videowidget.h
Normal file
71
include/videowidget.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
#include <QWidget>
|
||||
#include <QImage>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QComboBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
|
||||
#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;
|
||||
};
|
||||
Reference in New Issue
Block a user