PDA

View Full Version : Memory usage problem when setting style sheet



DiamonDogX
9th November 2009, 19:32
I have a GUI application in which I have several QPushButtons and when I click one I give it a red border by calling myPushButton->setStyle("border:3px solid #ff0000; background-color:black;"); and I set the style sheet on my other buttons to a blank string, i.e. myPushButton->setStyle( "" );

That's all I'm doing, but as I do this, my memory usage continually grows every time I click a button (i.e. when calling setStyleSheet). FYI, I'm currently developing on windows and looking at my task manager under the "Mem Usage" column. Any idea why this would be happening?

high_flyer
9th November 2009, 20:27
Did you try to see the mem usage when the stylesheet code is commented out?
It is more likely you have a memory leak somewhere else in your code.

DiamonDogX
9th November 2009, 20:37
Yes, I tried commenting out the setStyleSheet part, but when I do the mem usage doesn't grow like it does with it there...

high_flyer
10th November 2009, 09:37
but when I do the mem usage doesn't grow like it does with it there...
Doesn't grow *like*?
This distinction is important!
If it does grow, even if not by much, then the problem is somewhere in your code.
The amount of memory leaking may change as you use more resources, which you do when using the style.
But the leak it self is not in the style code, since you still leak if it commented out.

DiamonDogX
10th November 2009, 18:41
I eliminated the style sheets altogether and now I'm just changing the appearance of the buttons using setPalette(), but the problem still remains. The memory grows when changing the palette of the clicked one. If I keep clicking button1, then button2, then button1, etc. etc. back and forth the memory grows each time. Pretty sure it's not a leak somewhere else in the code because when I comment out the setPalette() call, the memory does not grow. Here's some code that may help clarify:


void MenuManager::changeButtonAppearance( QPushButton * button, const QColor & bgColor, const QColor & textColor, int bgAlpha )
{
if( button )
{
QPalette p( button->palette() );
QColor theBgColor( bgColor );
theBgColor.setAlpha( bgAlpha );
p.setColor( QPalette::Button, theBgColor );
p.setColor( QPalette::ButtonText, textColor );
button->setPalette( p );
}
}


void MenuManager::resetButtonStyles()
{
for( int i = 0; i < buttons.count(); i++ )
{
changeButtonAppearance(
buttons.at( i ),
QColor( Qt::black ),
QColor( Qt::yellow ),
128 );
}
}


void MenuManager::setButtonAsSelected( int index )
{
if( index >= 0 && index < buttons.count() )
{
resetButtonStyles();
changeButtonAppearance(
buttons.at( index ),
QColor( Qt::red ),
QColor( Qt::yellow ),
128 );
}
}

When I click a particular button, I call setButtonAsSelected() with an index depending on which button was clicked... intent is to set the background color of the button I clicked to red and set the other ones to black...

high_flyer
12th November 2009, 11:39
Can you show the code where you allocate the buttons?

RSX
12th November 2009, 11:59
Are you perhaps using custom QStyle for your application?

DiamonDogX
12th November 2009, 12:59
No, not using any custom styles.

Allocate the buttons? The are allocated according to the .ui file in which I made them and then I simply added them to a QList<QPushButton*> at runtime (buttons.append( _ui->button1 ), etc );

high_flyer
13th November 2009, 10:30
Can you then show the "working slot" for the clicked buttons?
Somewhere you have a either a leak, or it not a leak, but a valid allocation of resources, and it from what you are saying it is when you click the buttons, so it has to do with what every your code is doing at a respond to a button click.

DiamonDogX
16th November 2009, 14:25
void MenuManager::initButtons()
{
buttons.append( button1 );
buttons.append( button2 );
...
...

_buttonSignalMapper = new QSignalMapper( this );

foreach( QPushButton * button, buttons )
{
connect( button, SIGNAL( clicked() ), _buttonSignalMapper, SLOT( map() ) );

changeButtonAppearance( button,
QColor( Qt::black ),
QColor( Qt::yellow ),
128 );

buttons.at( i )->setWhatsThis( "command" + QString::number( i ) );
_buttonSignalMapper->setMapping( buttons.at( i ), buttons.at( i )->whatsThis() );
}

connect( _buttonSignalMapper, SIGNAL( mapped( const QString & ) ),
this, SLOT( performCommand( const QString & ) ) );

}


void MenuManager::performCommand( const QString & command )
{
if( command == "command0" )
{
setButtonAsSelected( 0 );
}
else if( command == "command1" )
{
setButtonAsSelected( 1 );
}

}

rokkamraja
17th November 2009, 15:15
Hi,

You probably could change your code a bit to remember the last clicked push button and change the appearance of just that + the new button that has been clicked. You seem to be looping over the whole button set.

Just use a variable prevIndex and set it to curIndex when you paint it red.

This might reduce the memory footprint.

- Raja.

DiamonDogX
17th November 2009, 18:49
I realize I am iterating over the whole button set and I did try what you said using a prevIndex, etc. but it does not seem to make a difference. I just don't understand what is going on here... why would the memory be growing every time I change the style of a button with a black background to have a style with a red background, etc... if I change one line in my changeButtonAppearance function and pass Qt::black instead of making a "color change" to Qt::red, the memory does not grow:


void MenuManager::setButtonAsSelected( int index )
{
if( index >= 0 && index < buttons.count() )
{
resetButtonStyles();
changeButtonAppearance(
buttons.at( index ),
QColor( Qt::black ), // if this is Qt::red or another color, memory grows :(
QColor( Qt::yellow ),
128 );
}
}

high_flyer
18th November 2009, 15:52
maybe you should run a profiler on it, see valgrind for example.