QVector append costum data type
-
Hi there
This might be a more C++ related question but since it uses the QVector I will try it here.
I've made a costum data type made of a simple struct that holds three short int's
struct RGB { short red; short green; short blue; };
then I created a QVector of type RGB
QVector<RGB> vec;
Now I want to append data to the QVector like this
blue = 3882; red = 9293; green = 3828; vec.append(RGB(red,green,blue));
I dont know how this kind of use is called but I use that very often in Qt with its own data types.
How can I make my own RGB data type able to do this in that way?Of cause when I try to compile this I get an error:
-
@pauledd said in QVector append costum data type:
struct RGB
{
short red;
short green;
short blue;
};Most likely you simply have to add a constructor to initialize the members to your struct:
struct RGB { RGB(short red, short green, short blue) : red(red), green(green), blue(blue) {} short red; short green; short blue; };
Happy New Year!
-
You are just using the wrong brackets:
vecImage.append(RGB(red,green,blue));
should bevecData.append(RGB{red,green,blue});
see http://en.cppreference.com/w/c/language/struct_initializationI tend to agree, however, with @aha_1980 in saying that a specific constructor is more robust or at least use the named version
-
Ok first
@aha_1980
I dont know why but this doesnt work. Here's my complete code:
mainwindow.h#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> struct RGB { RGB(short red, short green, short blue) : red(red), green(green), blue(blue) {} short red; short green; short blue; }; namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; QVector<RGB> vec; }; #endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); short red = 23; short green = 22; short blue = 28; vec.append(RGB(red,green,blue)); } MainWindow::~MainWindow() { delete ui; }
I get compile error:
/usr/include/qt5/QtCore/qvector.h:319: Fehler: no matching function for call to ‘RGB::RGB()’ new (from++) T(); ^
And @VRonin
if I use no constructor as suggested by aha_1980 and I use the curly brackets my app crashes, with constructor it does not crash, but compiles the same error as above. -
Hi
it tells you
"no matching function for call to ‘RGB::RGB()’"Which means, it cannot find a default constructor that takes no arguments.
which vector want for resize and moving stuff around. ( i think )
so you need to add that to your RGB class if it wants it.btw, Qt has QRgb :)
-
RGB(short red, short green, short blue) : red(red), green(green), blue(blue) {}
should beRGB(short red=0, short green=0, short blue=0) : red(red), green(green), blue(blue) {}
I use the curly brackets my app crashes
That means you have another problem somewhere else that is unrelated to this one. Check the stack trace to see what went wrong
-
ok, maybe I should go through this first:
Creating a Custom Type *Before we begin, we need to ensure that the custom type we are creating meets all the requirements imposed by QMetaType. In other words, it must provide: a public default constructor, a public copy constructor, and a public destructor.*
-
Ok , sorry I found I already asked something simmilar:
https://forum.qt.io/topic/71761/how-to-append-struct-to-qlist/9
I'll try to solve by my own and report back. -
I solved it.
My little struct exploded into a class as described in the above linked thread.
I added a standart/normal/copy constructor and a descructor,
a assignment operator and this, to me, mysterious "encapsulate members". I can just guess this is some kind of getter/setter accessing
the private members.class RGB { public: RGB(){} // standart constructor ~RGB(){} // destructor RGB(const RGB &other) :r_(other.r_),g_(other.g_),b_(other.b_){} // copy constructor RGB(short r, short g, short b) // normal constructor :r_(r), g_(g),b_(b){} RGB& operator = (const RGB& other) // assignment operator { r_ = other.r_; b_ = other.b_; g_ = other.g_; return *this; } const short& r() const {return r_;} // encapsulate members const short& g() const {return g_;} const short& b() const {return b_;} void setR(const short& val){r_ = val;} void setG(const short& val){g_ = val;} void setB(const short& val){b_ = val;} private: short r_; short g_; short b_; };
@mrjj said in QVector append costum data type:
btw, Qt has QRgb :)
If I read correctly QColor Class, the whole thing was not actually not just an exercise for me because QColor seems to not support 16bit colors like 0-65536 as such but only "getRgbF" with values from 0.0 to 1.0. Shure I could use something like 0.22816 but I would like to keep the same range as used in OpenCV Datatype cv::Vec3s.
The long and the short of it:
I can now use my RGB type directly to append a new value
to my QVector: -
mysterious "encapsulate members".
Hi, nothing mysterious about it. :)
It just means hide the details.
This give you the freedom to later change the class internal working without
breaking the program/ requires modifications outside class. -
- Your default constructor leaves the values initialised with junk, that's not a great idea usually
- Your destructor, copy constructor and assignment operators are all doing the default.
=default
them or remove them altogether short
is one of those rare cases where passing/returning by value is generally more efficient than by reference/pointer (16bits vs >=32bit)
class RGB { public: ~RGB()=default; // destructor RGB(const RGB &other)=default; // copy constructor RGB(short r=0, short g=0, short b=0) // normal constructor :r_(r), g_(g),b_(b){} RGB& operator = (const RGB& other)=default; // assignment operator short r() const {return r_;} // encapsulate members short g() const {return g_;} short b() const {return b_;} void setR(short val){r_ = val;} void setG(short val){g_ = val;} void setB(short val){b_ = val;} private: short r_; short g_; short b_; }