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:
    image

    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)));
    		}
    	}
    }
    
    
    
    

  • Moderators

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

  • Moderators

    @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?


  • Moderators

    @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 check QCombobox::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.



  • Ok, thanks a lot! Marked as solved!



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.