PDA

View Full Version : Marguee label + QQStringList + QTimer



prophet0
13th March 2012, 21:57
widgetmargueelabel.h


#ifndef _WIDGETMARQUEELABEL_H_
#define _WIDGETMARQUEELABEL_H_

#include <QLabel>
#include <QTimer>

class WidgetMarqueeLabel : public QLabel
{
Q_OBJECT

public: //Member Functions
enum Direction{LeftToRight,RightToLeft};
WidgetMarqueeLabel(QWidget *parent = 0);
~WidgetMarqueeLabel();
void show();
void setAlignment(Qt::Alignment);
int getSpeed();

public slots: //Public Member Slots
void setSpeed(int s);
void setDirection(int d);

protected: //Member Functions
void paintEvent(QPaintEvent *evt);
void resizeEvent(QResizeEvent *evt);
void updateCoordinates();

private: //Data Members
int px;
int py;
QTimer timer;
Qt::Alignment m_align;
int speed;
int direction;
int fontPointSize;
int textLength;

private slots: //Private Member Slots
void refreshLabel();
};
#endif /*_WIDGETMARQUEELABEL_H_*/


widgetmargueelabel.cpp


#include "widgetmargueelabel.h"
#include <QPainter>

WidgetMarqueeLabel::WidgetMarqueeLabel(QWidget *parent)
{
px = 0;
py = 15;
speed = 1;
direction = RightToLeft;
connect(&timer, SIGNAL(timeout()), this, SLOT(refreshLabel()));
timer.start(40);
}

void WidgetMarqueeLabel::refreshLabel()
{
repaint();
}

WidgetMarqueeLabel::~WidgetMarqueeLabel()
{}

void WidgetMarqueeLabel::show()
{
QLabel::show();
}

void WidgetMarqueeLabel::setAlignment(Qt::Alignment al)
{
m_align = al;
updateCoordinates();
QLabel::setAlignment(al);
}

void WidgetMarqueeLabel::paintEvent(QPaintEvent *evt)
{
QPainter p(this);
if(direction==RightToLeft)
{
px -= speed;
if(px <= (-textLength))
px = width();
}
else
{
px += speed;
if(px >= width())
px = - textLength;
}
p.drawText(px, py + fontPointSize, text());
p.translate(px,0);
}

void WidgetMarqueeLabel::resizeEvent(QResizeEvent *evt)
{
updateCoordinates();
QLabel::resizeEvent(evt);
}

void WidgetMarqueeLabel::updateCoordinates()
{
switch(m_align)
{
case Qt::AlignTop:
py = 10;
break;
case Qt::AlignBottom:
py = height()-10;
break;
case Qt::AlignVCenter:
py = height()/2;
break;
}
fontPointSize = font().pointSize()/2;
textLength = fontMetrics().width(text());
}

void WidgetMarqueeLabel::setSpeed(int s)
{
speed = s;
}

int WidgetMarqueeLabel::getSpeed()
{
return speed;
}

void WidgetMarqueeLabel::setDirection(int d)
{
direction = d;
if (direction==RightToLeft)
px = width() - textLength;
else
px = 0;
refreshLabel();
}



main.cpp


QStringList sClientIdData;
sClientIdData = _myParse->getClientID();

for ( QStringList::Iterator it = sClientIdData.begin(); it != sClientIdData.end(); ++it )
{
// debug shows both entries in the QStringList
}


/* Scrolling Text: Start */
ml = new WidgetMarqueeLabel(this);
ml->setTextFormat(Qt::RichText);
this->layout()->addWidget(ml);
ml->setAlignment(Qt::AlignVCenter);

ml->setText(/* STRING DATA HERE */);
ml->setFont(QFont("Arial", 20,20));
ml->setGeometry(80, 5, 731, 31);
ml->setStyleSheet("font: 16pt ""Trebuchet MS""; color: rgb(160, 160, 160)");
/* Scrolling Text: END */


What I'm trying to do is set the text of ml via a stringlist but 1 string at a time following the last character of the string so if the string list was "MyFirstString" and "MySecondString" once the Marguee label is DONE showing the last character of the string refresh the label with a new string and just keep looping it..

What is the best way to accomplish this task ?

please if you could point me in the right direction thanks a lot !

ChrisW67
14th March 2012, 02:51
Have the custom label emit a signal when a label has scrolled off the view. Connect that signal to a slot that feeds the next queued string to the label.

prophet0
14th March 2012, 18:07
Awesome I have the signal and its emitting but I'm having an issue with displaying 1 string at a time from my string list



void taxi::DoneScroll()
{
for ( QStringList::Iterator it = sClientIdData.begin(); it != sClientIdData.end(); ++it )
{
ml->setText(*it); //displays the last String in the List

}
}

wysota
14th March 2012, 18:44
for ( QStringList::Iterator it = sClientIdData.begin(); it != sClientIdData.end(); ++it )
{
ml->setText(*it); //displays the last String in the List

}

Could you explain what exactly would you like the above code to do?

prophet0
14th March 2012, 18:56
Well im not sure exactly how to get 1 string out of the list and then when called again get the next one

I'm trying to get 1 string from from the list and go to the next

wysota
14th March 2012, 19:02
But please try to analyze the quoted code and explain what you think should happen when it gets executed.

prophet0
15th March 2012, 14:59
I think it should out put whats in the QStringList, so my question is now how would i be able to change the above code to just display the first one [0] and when called again get the next one and just forever loop that?

wysota
15th March 2012, 15:05
Do exactly that. Display the first item and when you want another one to be displayed call the same code again just making it aware (though a kept state, e.g. an integer holding the index of the text currently being displayed) which item it should display next.

prophet0
15th March 2012, 17:16
for (int i = 0; i < sClientIdData.size();)
{
QString str = sClientIdData.at(i);
ml->setText(str);
i++;
}


for the above code i assume that for i = 0 then i < sClientIdData.size(); (size = 2) QString str = sClientIdData.at(i); so int i should be 0 settext of ml = str then increment by 1 i

but it does not work that way could you point out what i am doing wrong ?

wysota
15th March 2012, 20:50
Think what happens when this code is executed. Specifically what happens when setText() is called and when the next line of code is executed.

prophet0
15th March 2012, 21:00
I Solved my problem with



iterator = new QStringListIterator(sClientIdData);

if(iterator->hasNext())
{
ml->setText(iterator->next());
}
if(!iterator->hasNext())
{
iterator->toFront();
}



Works perfect now

wysota
15th March 2012, 22:19
And where have you put that? Because that's an equivalent of:


ml->setText(sClientIdData[i++]);
i = i % sClientIdData.size();

There are no loops here...

prophet0
16th March 2012, 04:44
In taxi.cpp in taxi::taxi


iterator = new QStringListIterator(sClientIdData);


and in taxi.cpp taxi::doneScroll()


if(iterator->hasNext())
{
ml->setText(iterator->next());
}
if(!iterator->hasNext())
{
iterator->toFront();
}


so everytime 1 string is scrolled out of view it emits a signal and gets the next string

the loop is what i require cause some strings will be minimal so i want it to repeat after it has hit the last string then go back to the front of the iterator

wysota
16th March 2012, 09:46
So now compare your original code and your current one, spot the difference and finally understand why the original didn't work.