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 ]