[PyQt4] Smooth text scrolling in QLabel (again)
Hello,
I'm trying to implement a QLabel with fixed width, which scrolls the text it shows if it's too long (as many multimedia players do, also known as Marquee effect).
It's basically the same question as in this thread: http://www.qtcentre.org/threads/3005...Text-Scrolling,
however I don't understand how I have to "alter QLabel and use QWidget::scroll() with a timer", which was the solution there.
What I've tried so far is using a QTimer together with QLabel.setIndent(QLabel.indent() + 1), which works fine, but scrolls in the wrong direction (values < 0 are ignored so QLabel.indent() - 1 wouldn't work).
So the question is how can I use the scroll function on the QLabel, because right now nothing happens with QLabel.scroll(x, y).
Sidenote: I'm using PyQt 4.8.6-1.
Thanks in advance,
Jay-D
Re: [PyQt4] Smooth text scrolling in QLabel (again)
so far I've been at least able to get scrolling by sticking a QLabel inside a QWidget and then calling
name_of_qwidget->scroll(-5,0) which makes it scroll to the left.
I haven't been able to actually see any MORE text than what's shown in the first place, though. I also don't know how to monitor when the text is off the widget and out of sight
here is some of my code
mainwindow.h:
#include <QTimer>
private slots:
void onScrollTimerTimeout();
private:
QTimer* m_scrollTimer;
mainwindow.cpp
m_scrollTimer=new QTimer();
connect(m_scrollTimer,SIGNAL(timeout()),this,SLOT( onScrollTimerTimeout()));
m_scrollTimer->start(500); //to start the timout process
void MainWindow::onScrollTimerTimeout()
{
//scrolls -5 pixels every .5 seconds
ui->scrollWidget->scroll(-5,0);
m_scrollTimer->start(500); //reset the timer to 500 milliseconds (half a second)
}
HOWEVER here is some code you might want to look at and use
http://qt-apps.org/content/show.php/...content=113690
you can see it in action herehttp://www.youtube.com/watch?v=AirpRX5EPF4
if I learn something after looking at the code for it I'll post it here
Re: [PyQt4] Smooth text scrolling in QLabel (again)
I changed WidgetMarqueeLabel.h and.cpp to the following.
Code:
#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,
int spd
=50,
int dir
=WidgetMarqueeLabel
::RightToLeft,
bool start
=FALSE);
~WidgetMarqueeLabel();
void show();
void setAlignment(Qt::Alignment);
int getSpeed();
public slots: //Public Member Slots
void setSpeed(int s);
void setDirection(int d);
void updateCoordinates();
protected: //Member Functions
private: //Data Members
bool autostart;
int px;
int py;
Qt::Alignment m_align;
int speed;
int direction;
int fontPointSize;
int textLength;
private slots: //Private Member Slots
void refreshLabel();
};
#endif /*_WIDGETMARQUEELABEL_H_*/
Code:
#include "WidgetMarqueeLabel.h"
#include <QPainter>
#include <QDebug>
WidgetMarqueeLabel
::WidgetMarqueeLabel(QWidget *parent,
int spd,
int dir,
bool start
){
px = 0;
py = 15;
speed = spd;
direction = dir;
autostart=start;
connect(&timer, SIGNAL(timeout()), this, SLOT(refreshLabel()));
if (autostart==FALSE){
if (fontMetrics().width(text())> width())
timer.start(10);
}
else
timer.start(10);
}
void WidgetMarqueeLabel::refreshLabel()
{
if(direction==RightToLeft)
{
px -=1;
if(px <= (-textLength))
px = width();
}
else
{
px +=1;
if(px >= width())
px = - textLength;
}
timer.start(speed);
repaint();
}
WidgetMarqueeLabel::~WidgetMarqueeLabel()
{}
void WidgetMarqueeLabel::show()
{
}
void WidgetMarqueeLabel::setAlignment(Qt::Alignment al)
{
m_align = al;
updateCoordinates();
}
{
p.drawText(px, py + fontPointSize, text());
p.translate(px,0);
}
{
updateCoordinates();
}
void WidgetMarqueeLabel::updateCoordinates()
{
px=0;
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());
if (textLength>width())
timer.start(10);
else{
timer.stop();
repaint();
}
}
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();
}
I changed a few things, including the paintEvent function. The scroll was too fast the way it was, so I made sure it was setup to the timer
that they had instead of just the paintEvent. I also added a few features, like only scrolling if the text amount is larger than the space.
If the text changes in my MainWindow.cpp I emit a SIGNAL songChanged and connect it to WidgetMarqueeLabel's SLOT updateCoordinates;
here is a snippet from my code:
Code:
song=new WidgetMarqueeLabel(ui->centralWidget,1);
song
->setObjectName
(QString::fromUtf8("song"));
song
->setGeometry
(QRect(60,
10,
281,
21));
connect(this,SIGNAL(songChanged()),song,SLOT(updateCoordinates()));
song->setText("hello");
song->setSpeed(100);
void MainWindow::onSourceChanged(Phonon::MediaSource source)
{
QMultiMap<QString,QString> tags=getTags(source);
if(tags.value("TITLE").isEmpty())
file=source.fileName().mid(source.fileName().lastIndexOf("/")+1,source.fileName().size());
else
file=tags.value("ARTIST")+"-"+tags.value("TITLE");
song->setText(file);
emit songChanged();
global_index=sources.indexOf(source);
populateList();
}
There isn't any reason to include 1 as a speed in my instantiation of song but at least you can see me setting the speed.
take a look at the examples in the zip file.
I tried to make a plugin for this to Designer. I was able to get Designer to display the widget, but as soon as I went to click on it it would crash Designer/Qt Creator. So I'm stuck with programatically adding a WidgetMarqueeLabel. If you have any info on this feel free to share cw9000@hotmail.com
Re: [PyQt4] Smooth text scrolling in QLabel (again)
After a brief look, I would advice to cache the text in a pixmap and draw that. It should be much faster. Also do not use repaint(). Use update().
Re: [PyQt4] Smooth text scrolling in QLabel (again)
Hi,
I wondered if it was possibile to reappear before the text that reaches the end of the last letter on the right:
I want something like this: for example (white space are 25):
Code:
WidgetMarqueeLabel
Wi dgetMarqueeLabel
tMarqueeLabel Widge
eLabel WidgetMarque
el WidgetMarqueeLa
WidgetMarqueeLabel
Is possibile?
thanks
Re: [PyQt4] Smooth text scrolling in QLabel (again)
Re: [PyQt4] Smooth text scrolling in QLabel (again)
Ehm, yes, it is possible. What exactly is the problem?
Re: [PyQt4] Smooth text scrolling in QLabel (again)
Look here: I no want wait the end of text for restart text at beginning..
But i want restart text before the beginning of screen.
Quote:
Originally Posted by
enaud
Hi,
I wondered if it was possibile to reappear before the text that reaches the end of the last letter on the right:
I want something like this: for example (white space are 25):
Code:
WidgetMarqueeLabel
Wi dgetMarqueeLabel
tMarqueeLabel Widge
eLabel WidgetMarque
el WidgetMarqueeLa
WidgetMarqueeLabel
Is possibile?
thanks
Re: [PyQt4] Smooth text scrolling in QLabel (again)
Hi enaud,
Since I'm on something realy simillar to your implemetation, did you make this Marquee effect happen in the end?
thanks.