Über... hinzugefügt, Icon hinzugefügt

This commit is contained in:
2026-06-09 23:15:29 +02:00
parent 2181f254d2
commit 92168ee5dc
19 changed files with 1039 additions and 88 deletions

View File

@@ -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
View 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
View 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;
};