Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 5

Qt-interest Archive, February 2007
Decrease QVector


Message 1 in thread

Hi everyone

I have a problem I hope some one can point me in the right direction.

I have three classes A B and C

Class A have a B and B have a C.

A can have multiple B's an B can Have multiple C's. I use spin boxes to
determine the amount of each class.I use a Qvector in class A to store B
and and a QVector in class B to store C. When I increase B and C it
displays the amount I want. The problem is when I decrease again it stays
as it was. Any help will be appreciated.
Here is a snippet of the code.

class A

Qvector<B*> b;

connect(aSpinBox, SIGNAL(valueChanged(int)), this, SLOT(createB(int)));

void A::createB(int cnt){
 if(b.size() > cnt){
  for( int i = cnt; i < b.size(); ++i){  
   b.remove(i);
   layout->removeWidget(b[i]);
  }
 }else{
  for (int i = b.size(); i < cnt; ++i){
   b.append(new B());
   layout->addWidget(b[i]);
  }
 }
 setLayout(layout);
}

--
 [ signature omitted ] 

Message 2 in thread

This is the first thing, which got my attention. You first remove an object from your
QVector and than use the QVector to get an pointer the the already removed
object to remove it from your layout?

>   for( int i = cnt; i < b.size(); ++i){  
>    b.remove(i);
>    layout->removeWidget(b[i]);
>   }

Guido


--
 [ signature omitted ] 

Message 3 in thread

On Monday 19 February 2007 14:37, Guido Seifert wrote:
> This is the first thing, which got my attention. You first remove an object
> from your QVector and than use the QVector to get an pointer the the
> already removed object to remove it from your layout?
>
> >   for( int i = cnt; i < b.size(); ++i){  
> >    b.remove(i);
> >    layout->removeWidget(b[i]);
> >   }
>
> Guido
>
>
I have changed it around and stil do the same.
for( int i = cnt; i < b.size(); ++i){ 
    layout->removeWidget(b[i]);
    b.remove(i);
}

--
 [ signature omitted ] 

Message 4 in thread

Chris schrieb:
> I have changed it around and stil do the same.
> for( int i = cnt; i < b.size(); ++i){ 
>     layout->removeWidget(b[i]);
>     b.remove(i);
> }

Perhaps you should explicitely destroy the widget instead of just 
deregistering it in layout and vector:

- layout->removeWidget(b[i]);
+ delete b[i];
   b.remove(i);

Martin

-- 
 [ signature omitted ] 

Message 5 in thread

On Monday 19 February 2007 15:13, Martin Gebert wrote:
> Chris schrieb:
> > I have changed it around and stil do the same.
> > for( int i = cnt; i < b.size(); ++i){
> >     layout->removeWidget(b[i]);
> >     b.remove(i);
> > }
>
> Perhaps you should explicitely destroy the widget instead of just
> deregistering it in layout and vector:
>
> - layout->removeWidget(b[i]);
> + delete b[i];
>    b.remove(i);
>
> Martin

Thanks Martin it is doing the trick.

--
 [ signature omitted ] 

Message 6 in thread

> > Perhaps you should explicitely destroy the widget instead of just
> > deregistering it in layout and vector:
> >
> > - layout->removeWidget(b[i]);
> > + delete b[i];
> >    b.remove(i);
> >
> > Martin
> 
> Thanks Martin it is doing the trick.

It might does the trick. But if there was a bug before, I am not sure it 
is completely gone, just because you deleted the object. Ok, you removed 
a memory leak, but I still see no reason why the removeWidget(b[i]) + 
b.remove(i) did not work. At least not for single steps.

Guido


--
 [ signature omitted ] 

Message 7 in thread

On Mon, Feb 19, 2007 at 05:29:36PM +0100, Guido Seifert wrote:
> > > Perhaps you should explicitely destroy the widget instead of just
> > > deregistering it in layout and vector:
> > >
> > > - layout->removeWidget(b[i]);
> > > + delete b[i];
> > >    b.remove(i);
> > >
> > > Martin
> > 
> > Thanks Martin it is doing the trick.
> 

STOP! DON'T! Did not think of it before, but according to docs:

void QLayout::addItem ( QLayoutItem * item ) 
The ownership of item is transferred to the layout, and it's the 
layout's responsibility to delete it.

If you remove the layout->removeWidget(b[i]); line and
delete the object yourself, you delete an object, which does not belong 
to you. You corrupt you memory.

Guido



--
 [ signature omitted ] 

Message 8 in thread

Guido Seifert wrote:
> > > > Perhaps you should explicitely destroy the widget instead of
just
> > > > deregistering it in layout and vector:
> > > >
> > > > - layout->removeWidget(b[i]);
> > > > + delete b[i];
> > > >    b.remove(i);
> > > >
> > > > Martin
> > >
> > > Thanks Martin it is doing the trick.
> >
> 
> STOP! DON'T! Did not think of it before, but according to docs:
> 
> void QLayout::addItem ( QLayoutItem * item )
> The ownership of item is transferred to the layout, and it's the
> layout's responsibility to delete it.
> 
> If you remove the layout->removeWidget(b[i]); line and
> delete the object yourself, you delete an object, which does not
belong
> to you. You corrupt you memory.

also from the docs:

void QLayout::removeItem ( QLayoutItem * item )

Removes the layout item item from the layout. It is the caller's
responsibility to delete the item.

so use this instead of removeWidget() ...

i also think there is an issue left with the index becoming invalid
after removing a widget...

Peter

--
 [ signature omitted ] 

Message 9 in thread

Hi,

Peter Prade wrote:
> void QLayout::removeItem ( QLayoutItem * item )
> 
> Removes the layout item item from the layout. It is the caller's
> responsibility to delete the item.

The docs also say that normally you don't use QLayoutItems directly. I 
would suggest that if you go ahead and delete the widget directly Qt 
will do "the right thing"...

Tim

--
 [ signature omitted ] 

Message 10 in thread

Hi there, does Qt support Aqua effects on mac? For example in Skype  
when we switch between tabs they "pulse" like whater

--
 [ signature omitted ] 

Message 11 in thread

On Mon, 2007-02-19 at 13:37 +0100, Guido Seifert wrote:
> This is the first thing, which got my attention. You first remove an object from your
> QVector and than use the QVector to get an pointer the the already removed
> object to remove it from your layout?
> 
> >   for( int i = cnt; i < b.size(); ++i){  
> >    b.remove(i);
> >    layout->removeWidget(b[i]);
> >   }
> 

Yes, that is definitely one fault. A second is that because i is
increasing and b.size() is decreasing ever time around the loop you will
only remove half of what you want. The loop control should be something
like

   for( int i = b.size()-1; i >= cnt; --i){  

Regards,

Stephen Jackson



--
 [ signature omitted ] 

Message 12 in thread

> Yes, that is definitely one fault. A second is that because i is
> increasing and b.size() is decreasing ever time around the loop you will
> only remove half of what you want. The loop control should be something
> like
> 
>    for( int i = b.size()-1; i >= cnt; --i){  

Right, but this should not matter as long as only the arrow buttons on the
QSpinBox are used and step 1 is selected. Ugly bug. :-)

Maybe this could be a problem:
From the QWidget::setLayout ( QLayout * layout ) docs:

If there already is a layout manager installed on this widget, QWidget won't let you install 
another. You must first delete the existing layout manager (returned by layout()) before you 
can call setLayout() with the new layout.

No idea what happens if you call setLayout more than once with a pointer of one and the same
layout. And increasing the object count seems to work. 

Guido


--
 [ signature omitted ]