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

Qt-interest Archive, February 2007
QSignalMapper memory? (was Re: Signal Slot)


Message 1 in thread

Iwas struggling with a similar issue with the QDialogButtonBox because of the custom colors I need.  I need to know which buttons are being pressed/released so that I can set the colors accordingly.   QSignalMapper looks like the answer.  I wish these advanced topics were touched on in the C++ GUI Programming with Qt4 book. 

One question - does Qt own the memory you allocate with a QSignalMapper?  If I have:

class MyButton: public QPushButton {
    MyButton(QString const & text, QWidget *parent = NULL);
...
signals:
    void clicked(QString const & text);
private:
    QSignalMapper mapper;
};
...
MyButton::MyButton(String const & text, QWidget *parent)
    :
        QPushButton(text, parent),
        mapper(new QSignalMapper())
{
    // make the mapping and connections
    //
}

Does ~MyButton have to delete the memory occupied by mapper?

Thanks in advance,
Susan
>Matthieu Brucher wrote:
>To: QT Newsletter <qt-interest@xxxxxxxxxxxxx>
>Sent: Thursday, February 22, 2007 7:01:35 AM
>Subject: Re: Signal Slot
>
>Suchi, Agrawal (IE10) wrote:
>> Hi,
>>
>> *Is there any way that I can pass a parameter to a slot which is not in
>> signal.*
>>
>> *Something like:*
>>
>> * *
>>
>> *For(int i=0;i<3;i++)*
>>
>> *            
>> CONNECT(obj1,SIGNAL(clicked()),obj2,SLOT(user_defined_slot(i)));*
>>
>> *The main issue is how to pass this \u201ci\u201d to t he slot called?*
>
>Check QSignalMapper.
>
>Matthieu

I was struggling with a similar issue with the QDialogButtonBox because of the custom colors I need.  I need to know which buttons are being pressed/released so that I can set the colors accordingly.   QSignalMapper looks like the answer.  I wish these advanced topics were touched on in the C++ GUI Programming with Qt4 book. 

One question - does Qt own the memory you allocate with a QSignalMapper?  If I have:

class MyButton: public QPushButton {
    MyButton(QString const & text, QWidget *parent = NULL);
...
signals:
    void clicked(QString const & text);
private:
    QSignalMapper mapper;
};
...
MyButton::MyButton(String const & text, QWidget *parent)
    :
        QPushButton(text, parent),
        mapper(new QSignalMapper())
{
    // make the mapping and connections
    //
}

Does ~MyButton have to delete the memory occupied by mapper?

Thanks in advance,
Susan




--
 [ signature omitted ] 

Message 2 in thread

> One question - does Qt own the memory you allocate with a 
> QSignalMapper?  If I have:
> 
> class MyButton: public QPushButton {
>     MyButton(QString const & text, QWidget *parent = NULL); ...
> signals:
>     void clicked(QString const & text);
> private:
>     QSignalMapper mapper;
> };
> ...
> MyButton::MyButton(String const & text, QWidget *parent)
>     :
>         QPushButton(text, parent),
>         mapper(new QSignalMapper())
> {
>     // make the mapping and connections
>     //
> }

You almost certainly are not using QSignalMapper correctly.  The
allocation you made in the above code creates a new QSignalMapper
object, and then sets your "mapper" object's parent to be the new
QSignalMapper object that you created.  At this point you would have two
QSignalMapper's floating around, "mapper" and one that is only
accessible by doing something like "mapper->parent()".

I think you want something more like:

MyButton::MyButton(String const & text, QWidget *parent)
     :
         QPushButton(text, parent),
         mapper(parent)

Sean

--
 [ signature omitted ] 

Message 3 in thread

>From: "Murphy, Sean M." <sean.murphy@xxxxxxxxxx>
>
>> One question - does Qt own the memory you allocate with a
>> QSignalMapper?  If I have:
>>
>> class MyButton: public QPushButton {
>>     MyButton(QString const & text, QWidget *parent = NULL); ...
>> signals:
>>     void clicked(QString const & text);
>> private:
>>     QSignalMapper mapper;
>> };
>> ...
>> MyButton::MyButton(String const & text, QWidget *parent)
>>     :
>>         QPushButton(text, parent),
>>         mapper(new QSignalMapper())
>> {
>>     // make the mapping and connections
>>     //
>> }
>
>You almost certainly are not using QSignalMapper correctly.  The
>allocation you made in the above code creates a new QSignalMapper
>object, and then sets your "mapper" object's parent to be the new
>QSignalMapper object that you created.  At this point you would have two
>QSignalMapper's floating around, "mapper" and one that is only
>accessible by doing something like "mapper->parent()".
>
>I think you want something more like:
>
>MyButton::MyButton(String const & text, QWidget *parent)
>     :
>         QPushButton(text, parent),
>         mapper(parent)
>
>Sean

True - in my code, I actually have:

MyButton::MyButton(String const & text, QWidget *parent)
  :
    QPushButton(text, parent),
    mapper(new QSignalMapper(this))     //  see the *this* as a parameter <=======
{
    // make the mapping and connections
    //
}

I forgot that when I wrote the original email.  I got this example from the Qt Assistant.

But - I still need to know whether to free mapper in the destructor of MyButton.

TIA,
Susan




--
 [ signature omitted ] 

Message 4 in thread

True - in my code, I actually have:

MyButton::MyButton(String const & text, QWidget *parent)
  :
    QPushButton(text, parent),
    mapper(new QSignalMapper(this))     //  see the *this* as a parameter <=======
{
    // make the mapping and connections
    //
}

I forgot that when I wrote the original email.  I got this example from the Qt Assistant.

But - I still need to know whether to free mapper in the destructor of MyButton.

TIA,
Susan

===============
This is most likely still wrong, unless you updated your definiton of mapper to be a pointer.
 
in your MyButton class, make sure mapper is defined as
QSignalMapper * mapper;
 
Scott

--
 [ signature omitted ] 

Message 5 in thread

On 2/22/07, susan@xxxxxxxxxxxx <susan@xxxxxxxxxxxx> wrote:
> True - in my code, I actually have:
>
> MyButton::MyButton(String const & text, QWidget *parent)
>   :
>     QPushButton(text, parent),
>     mapper(new QSignalMapper(this))     //  see the *this* as a parameter <=======
> {
>     // make the mapping and connections
>     //
> }
>
> I forgot that when I wrote the original email.  I got this example from the Qt Assistant.
>
> But - I still need to know whether to free mapper in the destructor of MyButton.

No. QObjects automatically delete their children - see
http://doc.trolltech.com/4.2/qobject.html#QObject

Still, it seems very strange to have a signal mapper *inside* a
QPushButton. Why  are you doing that? A normal use of a signal mapper
would be inside a QWidget mapping the clicked() signal of various
buttons to a single clicked(int) signal.

-- 
 [ signature omitted ] 

Message 6 in thread

> 
> MyButton::MyButton(String const & text, QWidget *parent)
>   :
>     QPushButton(text, parent),
>     mapper(new QSignalMapper(this))     //  see the *this* as 
> a parameter <=======
> {
>     // make the mapping and connections
>     //
> }
> 
> I forgot that when I wrote the original email.  I got this 
> example from the Qt Assistant.
> 
> But - I still need to know whether to free mapper in the 
> destructor of MyButton.

Well according to this line in your header file: 

> >> private:
> >>     QSignalMapper mapper;

You shouldn't be doing what you have above at all, since you are trying
to assign a QSignalMapper pointer to a QSignalMapper object, so I assume
your header really reads:

private:
	QSignalMapper *mapper; // <- notice it's now a pointer

If that is what your header really looks like, then no you don't need to
call
	delete mapper;
anywhere in your code, because you've set mapper up to be a child of
your MyButton class, so when your MyButton object goes out of scope, it
will first delete mapper.  

You can read up a little more about Qt's object model
(http://doc.trolltech.com/4.2/object.html) but in general if you
properly assign a parent to a QObject based item, Qt will take care of
deleting it for you.  This takes a bit of time to get used to since in
every C++ class you've learned "if you use 'new' to create something,
you must call 'delete' to get rid of it".

Sean


--
 [ signature omitted ] 

Message 7 in thread

>in your MyButton class, make sure mapper is defined as
>QSignalMapper * mapper;
 
Yes - its a pointer.  Since I pass "this" to the constructor, I can assume that MyButton no longer owns the memory, right?

Thanks,
Susan





--
 [ signature omitted ] 

Message 8 in thread

On 2/22/07, susan@xxxxxxxxxxxx <susan@xxxxxxxxxxxx> wrote:
> >in your MyButton class, make sure mapper is defined as
> >QSignalMapper * mapper;
>
> Yes - its a pointer.  Since I pass "this" to the constructor, I can assume that MyButton no longer owns the memory, right?

I'm not sure what you mean by "owns the memory", but passing `this' (a
MyButton*) as the parent argument to QSignalMapper's constructor means
that the QSignalMapper will be destroyed when the MyButton is
destroyed. The documentation states this explicitly - see
http://doc.trolltech.com/4.2/qobject.html#QObject and
http://doc.trolltech.com/4.2/qobject.html#dtor.QObject

-- 
 [ signature omitted ] 

Message 9 in thread


>You can read up a little more about Qt's object model
>(http://doc.trolltech.com/4.2/object.html) but in general if you
>properly assign a parent to a QObject based item, Qt will take care of
>deleting it for you.  This takes a bit of time to get used to since in
>every C++ class you've learned "if you use 'new' to create something,
>you must call 'delete' to get rid of it".

You are right.  What I put in the post wasn't exactly what was in my
sources.  I had pointers and Qt takes care of the memory for me for all
QObject entities.  I understand this and my question was a result of my mistake in my own code!  :-[



Thanks for your patience and my apologies for not being clear.  Lesson
learned on my end.  I will be sure to make my next posts clear and
correct.
--Susan







--
 [ signature omitted ]