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:
    0_1514892197422_Bildschirmfoto_2018-01-02_12-22-24.png


  • Qt Champions 2017

    @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 be vecData.append(RGB{red,green,blue}); see http://en.cppreference.com/w/c/language/struct_initialization

    I 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.


  • Qt Champions 2017

    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 be RGB(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.*
    

    http://doc.qt.io/qt-5/custom-types.html



  • @mrjj said in QVector append costum data type:

    btw, Qt has QRgb :)

    Yes :D but I would take this as a lesson because I am sure I would stumble over
    the problem in the future.



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

    0_1514967617001_Bildschirmfoto_2018-01-03_09-15-38.png


  • Qt Champions 2017

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


  • Thanks for your information/hints! I will correct the remaining suggestions, and this should be solved.


Log in to reply
 

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