how to add item QComboBox with QVideoFrame::PixelFormat?
-
Hi there,
I want to fill a QComboBox with all supported pixelformats of a given QCamera. I load the camera and I fill the QListQVideoFrame::PixelFormat Object "suppPixFmt" with camera->supportedViewfinderPixelFormats(). This works so far an I can print one single format with qDebug() << suppPixFmt->at(1);
Now I want to fill a QComboBox with the formats list but my fist attempt ended in:no known conversion for argument 1 from 'const QVideoFrame::PixelFormat' to 'const QString&'
My next thought was to use static_cast to convert it to QString but then the QComboBox is filled with stange Unicode? text:
Does someone know what's going wrong here?
Thats the code:
mainwindow.cpp#include "mainwindow.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QWidget(parent) { setFixedSize(800,600); move(600,250); comboBoxFormats = new QComboBox(this); camera = new QCamera(this); suppPixFmt = new QList<QVideoFrame::PixelFormat>; connect(camera, &QCamera::statusChanged, this, &MainWindow::updatedStatus); camera->load(); } MainWindow::~MainWindow() { } void MainWindow::updatedStatus(){ qDebug() << camera->status(); if(camera->status() == QCamera::LoadedStatus) { qDebug()<< "loaded & filling supported formats"; foreach (QVideoFrame::PixelFormat fmt, camera->supportedViewfinderPixelFormats()) { suppPixFmt->append(fmt); } for (int i = 0;i < suppPixFmt->size();i++){ comboBoxFormats->addItem(static_cast<QString>(suppPixFmt->at(i))); } } }
-
@pauledd said in how to add item QComboBox with QVideoFrame::PixelFormat?:
Does someone know what's going wrong here?
yes, its impossible to convert a enum to a string. Converting it by casting will make QString interpret it as unicode as you already noticed.
In Qt you could use QMetaObject to traverse a class' (registered) enum and use it to fill the combobox.
But QVideoFrame unfortunately doesn't inherit from QObject nor its a Q_GADGET, so it doesn't have a meta object.So you will have to fill the combobox with the string values yourself.
-
Ok, thank you for enlightening me :)
I created a struct that contains the Format QString and the corresponding number int. I created a QVector with that struct and filled it with a for loop - switch statement. I think it is awkward but it seems to work, my QComboBox gets filled with available pixelformats.
structs.h
#ifndef STRUCTS_H #define STRUCTS_H #include <QString> struct PixFmt{ unsigned int i; QString format; }; #endif // STRUCTS_H
mainwindow.cpp
#include "mainwindow.h" #include <QDebug> #include "structs.h" MainWindow::MainWindow(QWidget *parent) : QWidget(parent) { setFixedSize(800,600); move(600,250); comboBoxFormats = new QComboBox(this); vl = new QVBoxLayout(this); camera = new QCamera(this); suppPixFmt = new QList<QVideoFrame::PixelFormat>; connect(camera, &QCamera::statusChanged, this, &MainWindow::updatedStatus); camera->load(); } MainWindow::~MainWindow() { } void MainWindow::updatedStatus(){ PixFmt pfmt; QVector<PixFmt> vPixFmt; if(camera->status() == QCamera::LoadedStatus) { qDebug()<< "loaded & filling supported formats"; foreach (QVideoFrame::PixelFormat fmt, camera->supportedViewfinderPixelFormats()) { suppPixFmt->append(fmt); } for (int i=0;i<suppPixFmt->size();i++) { switch (suppPixFmt->at(i)) { case 0: pfmt.i = 0;pfmt.format = "Invalid"; vPixFmt.push_back(PixFmt(pfmt)); break; case 1: pfmt.i = 1;pfmt.format = "ARGB32"; vPixFmt.push_back(PixFmt(pfmt)); break; case 2: pfmt.i = 2;pfmt.format = "ARGB32_Premultiplied"; vPixFmt.push_back(PixFmt(pfmt)); break; case 3: pfmt.i = 3;pfmt.format = "RGB32"; vPixFmt.push_back(PixFmt(pfmt)); break; case 4: pfmt.i = 4;pfmt.format = "RGB24"; vPixFmt.push_back(PixFmt(pfmt)); break; case 5: pfmt.i = 5;pfmt.format = "RGB565"; vPixFmt.push_back(PixFmt(pfmt)); break; case 6: pfmt.i = 6;pfmt.format = "RGB555"; vPixFmt.push_back(PixFmt(pfmt)); break; case 7: pfmt.i = 7;pfmt.format = "ARGB8565_Premultiplied"; vPixFmt.push_back(PixFmt(pfmt)); break; case 8: pfmt.i = 8;pfmt.format = "BGRA32"; vPixFmt.push_back(PixFmt(pfmt)); break; case 9: pfmt.i = 9;pfmt.format = "BGRA32_Premultiplied"; vPixFmt.push_back(PixFmt(pfmt)); break; case 10: pfmt.i = 10;pfmt.format = "BGR32"; vPixFmt.push_back(PixFmt(pfmt)); break; case 11: pfmt.i = 11;pfmt.format = "BGR24"; vPixFmt.push_back(PixFmt(pfmt)); break; case 12: pfmt.i = 12;pfmt.format = "BGR565"; vPixFmt.push_back(PixFmt(pfmt)); break; case 13: pfmt.i = 13;pfmt.format = "BGR555"; vPixFmt.push_back(PixFmt(pfmt)); break; case 14: pfmt.i = 14;pfmt.format = "BGRA5658_Premultiplied"; vPixFmt.push_back(PixFmt(pfmt)); break; case 15: pfmt.i = 15;pfmt.format = "AYUV444"; vPixFmt.push_back(PixFmt(pfmt)); break; case 16: pfmt.i = 16;pfmt.format = "AYUV444_Premultiplied"; vPixFmt.push_back(PixFmt(pfmt)); break; case 17: pfmt.i = 17;pfmt.format = "YUV444"; vPixFmt.push_back(PixFmt(pfmt)); break; case 18: pfmt.i = 18;pfmt.format = "YUV420P"; vPixFmt.push_back(PixFmt(pfmt)); break; case 19: pfmt.i = 19;pfmt.format = "YV12"; vPixFmt.push_back(PixFmt(pfmt)); break; case 20: pfmt.i = 20;pfmt.format = "UYVY"; vPixFmt.push_back(PixFmt(pfmt)); break; case 21: pfmt.i = 21;pfmt.format = "YUYV"; vPixFmt.push_back(PixFmt(pfmt)); break; case 22: pfmt.i = 22;pfmt.format = "NV12"; vPixFmt.push_back(PixFmt(pfmt)); break; case 23: pfmt.i = 23;pfmt.format = "NV21"; vPixFmt.push_back(PixFmt(pfmt)); break; case 24: pfmt.i = 24;pfmt.format = "IMC1"; vPixFmt.push_back(PixFmt(pfmt)); break; case 25: pfmt.i = 25;pfmt.format = "IMC2"; vPixFmt.push_back(PixFmt(pfmt)); break; case 26: pfmt.i = 26;pfmt.format = "IMC3"; vPixFmt.push_back(PixFmt(pfmt)); break; case 27: pfmt.i = 27;pfmt.format = "IMC4"; vPixFmt.push_back(PixFmt(pfmt)); break; case 28: pfmt.i = 28;pfmt.format = "Y8"; vPixFmt.push_back(PixFmt(pfmt)); break; case 29: pfmt.i = 29;pfmt.format = "Y16"; vPixFmt.push_back(PixFmt(pfmt)); break; case 30: pfmt.i = 30;pfmt.format = "Jpeg"; vPixFmt.push_back(PixFmt(pfmt)); break; case 31: pfmt.i = 31;pfmt.format = "CameraRaw"; vPixFmt.push_back(PixFmt(pfmt)); break; case 32: pfmt.i = 32;pfmt.format = "AdobeDng"; vPixFmt.push_back(PixFmt(pfmt)); break; case 33: pfmt.i = 33;pfmt.format = "User"; vPixFmt.push_back(PixFmt(pfmt)); break; default: pfmt.i = 0;pfmt.format = "unknown Pixelformat"; vPixFmt.push_back(PixFmt(pfmt)); break; } } } for (int i=0;i<vPixFmt.size();i++) { comboBoxFormats->addItem(vPixFmt[i].format); } }
-
@pauledd
yes, thats the only way to achieve what you want.
But i recommend that you use the actual enum values instead the int values like you do now.
Also this code can be dramatically improved (regarding performance):QString pixelFormatToString( QVideoFrame::PixelFormat f ) { switch( f ) { default: case QVideoFrame::Format_Invalid: return QLatin1String("Invalid"); case QVideoFrame::Format_ARGB32: return QLatin1String("ARGB32"); ... } } void MainWindow::updatedStatus(){ if(camera->status() == QCamera::LoadedStatus) { qDebug()<< "loaded & filling supported formats"; foreach (QVideoFrame::PixelFormat fmt, camera->supportedViewfinderPixelFormats()) { comboBoxFormats->addItem( pixelFormatToString(fmt), QVariant::fromValue<int>(fmt)); //store it to the user data so you can retrieve it again with QComboBox::itemData() upon selection change } } }
-
@raven-worx said in how to add item QComboBox with QVideoFrame::PixelFormat?:
QVariant::fromValue<int>(fmt));
What does this? Is it returning the format corresponding int number from the pixelformat enum?
-
@pauledd
it stores the (int
explicitly in this case) value of the enum inside a QVariant.
This is just for convenience, to store the value along with the combobox item.
As i said checkQCombobox::itemData()
, if you want to retrieve the value (and cast it back to a QVideoFrame::PixelFormat enum type) when the selection changes in the combobox.