View Full Version : Smooth text scrolling
francesco.frankie
26th November 2010, 21:55
Hello!
I'm writing a program that should render the text embedded in a QTextDocument on a QGraphicsView, the text must be scaled and smoothly scrolled.
To do this job I've inherited the class QGraphicsItem and implemented the funciont paint, after the item is added to a QGraphicsScene that calls the function advance() every 30 milliseconds.
here is the code of the paint function:
void ScrollTextGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
if(currentDocument){
painter->setRenderHint(QPainter::SmoothPixmapTransform);
painter->translate(0,-scrollValue);
painter->scale(renderScale.width(),renderScale.height());
QAbstractTextDocumentLayout::PaintContext pcontext;
pcontext.palette.setColor(QPalette::Text, scrollScene->getDefaultTextColor());
pcontext.clip = QRectF(0,scrollValue/renderScale.height(),
renderSize.width()/renderScale.width(),
renderSize.height()/renderScale.height());
currentDocument->documentLayout()->draw(painter,pcontext);
}
}
The matter is if the result is almost reasonable for light-weight documents and for low scale factor, the performances turn down even for a small portion of text (few lines) scaled and drawn in a window 800x600.
Did i forget some optimization? Are there ways for improve the draw algorithm (for example using a QGLWidget)?
Have you some hints or suggestions?
thanks for the attention
Regards
wysota
27th November 2010, 01:13
Is there a reason why you didn't use QGraphicsTextItem?
francesco.frankie
27th November 2010, 18:35
Thank you for your reply.
Yes, I've tried it, but the performance problem persist.
Do you have other advices?
wysota
27th November 2010, 18:39
What is the performance problem? Please provide an example.
francesco.frankie
28th November 2010, 10:32
OK, I've made some test. Although the CPU level is low, the scroll animation isn't smooth, indeed depends on the resolution of the window where the scene is placed. I think the matter is resize and scale the scene...
For the animation I connect a timeout event of a timer with the function "advance" of the scene. The painter of the graphics item is moved by a number of pixel depends on the time elapsed sine last drawing.
tbscope
28th November 2010, 12:07
That's still not an example.
Here are a few:
http://doc.qt.nokia.com/4.7/examples-animation.html
I made a little test with a graphicsview and a qgraphicsproxywidget containing a label and using qpropertyanimation. The animation is smooth.
francesco.frankie
28th November 2010, 21:23
thank you guys for the attention and the support, and sorry if i wasn't able to provide a clear question.
My program should scroll in a full screen window a very large QTextDocument, about 5 lines in the same moment. I've tried several ways to perform the animation and render the text, but I wasn't able to obtain a real smooth and flicker-free animation.
In your opinion, which is the best way to do that? I followed the Animation tutorial and read articles about QT Graphics View Framework, but I didn't find the answer.
wysota
28th November 2010, 23:36
Why don't you just write a short (up to 30 lines of code) example demonstrating the problem?
francesco.frankie
29th November 2010, 21:32
Why don't you just write a short (up to 30 lines of code) example demonstrating the problem?
Well, here is a quick example about what i told.
I made a main window with a QTextEdit and a PushButton, let's try to copy and paste some text and click "start"
In this case I used a QGraphicsTextItem (as suggested by wysota) a timer and the "translate" method to arrange the scrolling.
The result (at least on my computer) flickers and isn't smooth.
Ok, this is a real simple example, but starting from this code, how can i improve the results?
Or...should I chose a totally different way?
//file: mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui/QApplication>
#include <QMainWindow>
#include <QGraphicsTextItem>
#include <QPushButton>
#include <QTextEdit>
#include <QGraphicsView>
#include <QGraphicsTextItem>
#include <QTimeLine>
#include <QTimer>
#include <QTime>
#include <QRect>
#include <QPushButton>
#include <QVBoxLayout>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0) : QMainWindow(parent){
QVBoxLayout* layout = new QVBoxLayout();
pushButton = new QPushButton("start");
textEdit = new QTextEdit();
layout->addWidget(textEdit);
layout->addWidget(pushButton);
QWidget* central = new QWidget();
central->setLayout(layout);
setCentralWidget(central);
connect(pushButton, SIGNAL(clicked()),SLOT(start()));
}
~MainWindow(){
}
QGraphicsView* view;
QGraphicsTextItem * text ;
QGraphicsScene* scene;
QPushButton* pushButton;
QTextEdit* textEdit;
QTime* timeSinceLastUpdate;
public slots:
void start(){
scene = new QGraphicsScene();
text = new QGraphicsTextItem();
text->setDocument(textEdit->document());
text->scale(6,6);
text->setPos(-100,0);
text->setTextWidth(140);
scene->addItem(text);
scene->setSceneRect(0,0,400,400);
view = new QGraphicsView(scene);
view->fitInView(view->sceneRect(),Qt::KeepAspectRatio);
view->setRenderHint(QPainter::SmoothPixmapTransform);
view->showFullScreen();
QTimer* sctT = new QTimer();
connect(sctT,SIGNAL(timeout()),SLOT(scroll()));
sctT->start(30);
timeSinceLastUpdate = new QTime();
timeSinceLastUpdate->start();
}
void scroll(){
int time = timeSinceLastUpdate->elapsed(); //make the scrolling indipendent from frame rate
float scrollValue = (40.0 * float(time))/1000.0;
text->translate(0,-scrollValue);
timeSinceLastUpdate->restart();
}
};
#endif // MAINWINDOW_H
file: main.cpp
#include <QtGui/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Thank for the support!
wysota
29th November 2010, 22:16
The animation is fluent on my machine but you can try this:
#include <QtGui>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0) : QMainWindow(parent){
QVBoxLayout* layout = new QVBoxLayout();
pushButton = new QPushButton("start");
textEdit = new QTextEdit();
layout->addWidget(textEdit);
layout->addWidget(pushButton);
QWidget* central = new QWidget();
central->setLayout(layout);
setCentralWidget(central);
connect(pushButton, SIGNAL(clicked()),SLOT(start()));
}
QGraphicsView* view;
QGraphicsTextItem * text ;
QGraphicsScene* scene;
QPushButton* pushButton;
QTextEdit* textEdit;
public slots:
void start(){
scene = new QGraphicsScene();
text = new QGraphicsTextItem();
text->setDocument(textEdit->document());
text->scale(6,6);
text->setPos(-100,0);
text->setTextWidth(140);
scene->addItem(text);
scene->setSceneRect(0,0,400,400);
view = new QGraphicsView(scene);
view->fitInView(view->sceneRect(),Qt::KeepAspectRatio);
view->setRenderHint(QPainter::SmoothPixmapTransform);
view->showFullScreen();
// the important part:
QPropertyAnimation *anim = new QPropertyAnimation(text, "pos", text);
anim->setStartValue(text->pos());
anim->setEndValue(QPointF(-100, -1000));
anim->setDuration(5000);
anim->start();
}
};
#include "main.moc"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.