-3

i have a class that has lot of problem with containers ,this time if i create my objects with non default constructor function i can't control the object in a container at all(change value , visible ...) ; but if i define my object with default constructor i can do it easily .

Control.h

class Controls : public QObject
{

private:

  QHBoxLayout *Layout ;
  string Controlname;
  QLabel *Label ;

  QSpinBox *Spin ;


public:
  QSlider *Slider ;
  Controls(QLayout &Parent , string name , const int &Default_value);
  Controls(const Controls &copy);
  Controls();
  Controls(QLayout &Parent);
  ~Controls();


  QLabel *  Get_Label()const { return Label ; }
  QSlider *  Get_Slider()const { return Slider ; }
  QSpinBox *  Get_Spin()const { return Spin ; }
  QHBoxLayout *  Get_Layout() {return Layout;}

  void SetValue(const int &newvalue);

  Controls &operator= (const Controls &copy);


};

controls.cpp

#include "Interface.h"
Controls &Controls::operator= (const Controls &copy)
{
  Slider->setValue(copy.Get_Slider()->value());
  Slider->setOrientation(Qt::Horizontal);
  Label->setText(copy.Get_Label()->text());
  Spin->setValue(copy.Get_Spin()->value());

  Layout->addWidget(Label , 0 , 0);
  Layout->addWidget(Slider , 0 , 0);
  Layout->addWidget(Spin , 0 , 0);

  QObject::connect(Slider , SIGNAL(valueChanged(int) ) , 
                   Spin , SLOT(setValue(int)));
  QObject::connect(Spin , SIGNAL(valueChanged(int) ) , 
                   Slider , SLOT(setValue(int)));

  return *this;
}

Controls::Controls(const Controls &copy)
{
  Label = new QLabel()   ;
  Slider = new QSlider()   ;
  Spin = new QSpinBox()  ;
  Layout = new QHBoxLayout();

  Slider->setValue(copy.Get_Slider()->value());
  Slider->setOrientation(Qt::Horizontal);
  Label->setText(copy.Get_Label()->text());
  Spin->setValue(copy.Get_Spin()->value());

  Layout->addWidget(Label , 0 , 0);
  Layout->addWidget(Slider , 0 , 0);
  Layout->addWidget(Spin , 0 , 0);

  QObject::connect(Slider , SIGNAL(valueChanged(int) ) , 
                   Spin , SLOT(setValue(int)));
  QObject::connect(Spin , SIGNAL(valueChanged(int) ) , 
                   Slider , SLOT(setValue(int)));
}

Controls::Controls()
{
  Label =  new QLabel()  ;
  Slider = new QSlider()   ;
  Spin = new QSpinBox()  ;
  Layout = new QHBoxLayout();

  Slider->setValue(0);
  Slider->setOrientation(Qt::Horizontal);
  Label->setText(QString ("unamed"));
  Spin->setValue(0);


  Layout->addWidget(Label , 0 , 0);
  Layout->addWidget(Slider , 0 , 0);
  Layout->addWidget(Spin , 0 , 0);

  QObject::connect(Slider , SIGNAL(valueChanged(int) ) , 
                   Spin , SLOT(setValue(int)));
  QObject::connect(Spin , SIGNAL(valueChanged(int) ) , 
                   Slider , SLOT(setValue(int)));
}


Controls::Controls(QLayout &Parent , string name , const int &Default_value)
{
  Controlname = name ;

  Label =  new QLabel() ;
  Slider = new QSlider()  ;
  Spin =  new QSpinBox()  ;
  Layout = new QHBoxLayout();

  Slider->setValue(Default_value);
  Slider->setOrientation(Qt::Horizontal);
  Label->setText(QString (name.c_str()));
  Spin->setValue(Default_value);


  Layout->addWidget(Label , 0 , 0);
  Layout->addWidget(Slider , 0 , 0);
  Layout->addWidget(Spin , 0 , 0);

  QObject::connect(Slider , SIGNAL(valueChanged(int) ) , 
                   Spin , SLOT(setValue(int)));
  QObject::connect(Spin , SIGNAL(valueChanged(int) ) , 
                   Slider , SLOT(setValue(int)));

  Parent.addItem(Layout);
}

void Controls::SetValue(const int &newvalue)
{
  Slider->setValue(newvalue);
}

Controls::~Controls()
{
}

main.cpp

int main()
{
  QApplication app (argc , argv );

  QVBoxLayout layout ;
  QLabel  Image  ;
  QWidget  Panel  ;
  Camera  Cm   ;


  vector <Controls> g ;
  g.push_back(Controls(layout ,"c1" , 33));
  g.push_back(Controls(layout ,"c2" , 13));
  g.push_back(Controls(layout ,"c3" , 63));
  g.push_back(Controls(layout ,"c1" , 33));


  for ( int x =0 ; x<g.size() ; x++)
  {
    g.at(x).SetValue(33); ////not work 

  }

  vector <Controls> g2 ;
  g2.push_back(Controls());
  g2.push_back(Controls());
  g2.push_back(Controls());
  g2.push_back(Controls());


  for ( int x =0 ; x<g2.size() ; x++)
  {
    layout.addItem(g2.at(x).Get_Layout());
    g2.at(x).SetValue(33); ////this  work

  }


  Panel.setLayout(&layout);
  Panel. show();

  return app.exec();

  return 0;
}
pmr
  • 58,701
  • 10
  • 113
  • 156
  • 1
    TLDR. Your copy constructor or assignment operator are probably the problem. Thats what normally causes this problem as containers copy and/or assign objects around. – Rafael Baptista Oct 23 '12 at 16:48
  • thanks for reply !i think this is the problem , i try to solve it but , i can't see any problem – user1728234 Oct 23 '12 at 16:57
  • And what's with the `QXxx * const` return types? You do know that the `const` is ignored in this context. – James Kanze Oct 23 '12 at 17:01
  • i edit the code ! please check it , any help to find the problem in my code please – user1728234 Oct 23 '12 at 17:12
  • i think my problem is in layout ( please check this , http://stackoverflow.com/questions/12952912/vectorpush-back-myclass-not-work-for-non-default-constructor?rq=1), but can't find anyway to solve it – user1728234 Oct 23 '12 at 17:23
  • You should shorten your question down to show the problem at its most basic. What does "Not work"? What is the error? – Dennis Oct 23 '12 at 17:30
  • my problem is i can't call method for my object that stored in std::vector (std::vector::at(0//example).somefunction() ) doesn't work – user1728234 Oct 23 '12 at 17:34
  • You *must* use the `Q_OBJECT` macro when subclassing `QObject`, it prevents use like this (amongst other important things). – cmannett85 Oct 23 '12 at 19:25

1 Answers1

2

You should not have a copy constructor or assignment operator for Controls at all, and you should be storing values of type Controls* in your vector instead of type Controls.

A copy-constructor that creates GUI objects is highly suspect. There's a reason QLabel, QSlider, QSpinBox and QHBoxLayout don't have copy constructors themselves. It makes for very slow code, and quickly becomes a confusing mess.

In short, you should almost never have a copy-constructor for objects that inherit from QObject.

cgmb
  • 4,284
  • 3
  • 33
  • 60
  • I cannot say for certain whether you are right becasue I don't use Qt, but I'd bet quite a bit on it. On Windows, it would be a nightmare of forms, parents, component lists, control lists, GDI/Windows handles, CreateWindow() etc. etc. to deep-copy a Windows control - horrifying prospect. – Martin James Oct 23 '12 at 19:19
  • +1 This is such important Qt concept that the `Q_OBJECT` macro automates it: https://qt-project.org/doc/qt-4.8/qobject.html#no-copy-constructor – cmannett85 Oct 23 '12 at 19:23