1 Attachment(s)
Create a marquee with QGraphicsScene
Hi all,
I'm looking to create a marquee like the ones we could watch on TV, normally horizontal scrolls. What I'm having is a lot of flickering on the animation, and I would like to have other opinions because I'm a newbie on Qt Graphics.
If I resize the window, the animation stops, is there a way to avoid that? I don't know if there is a way to have a thread for the scene.
Here is the main code I'm using, but you can find attached all the project.
Code:
{
setCacheMode(DeviceCoordinateCache);
_boundingRect
= QRectF(0,
0,
960,
220);
_animationSpeed = 0.5;
}
QRectF Item
::boundingRect() const {
return _boundingRect;
}
{
painter->setBrush(Qt::yellow);
painter->drawRoundedRect(2, 2, 84, 84, 4, 4);
painter
->setBrush
(QColor(50,
50,
50));
painter->drawRoundedRect(90, 2, 84, 84, 4, 4);
painter->drawRoundedRect(176, 2, 534, 84, 4, 4);
painter->drawRoundedRect(712, 2, 245, 84, 4, 4);
}
void Item::advance(int phase)
{
if (phase == 1)
{
moveBy(-(_animationSpeed), 0.0);
}
}
void Item::setAnimationSpeed(qreal value)
{
_animationSpeed = value;
}
Code:
MainWindow
::MainWindow(QWidget *parent
) : ui(new Ui::MainWindow)
{
ui->setupUi(this);
scene->setBackgroundBrush(Qt::black);
ui->graphicsView->setScene(scene);
ui->graphicsView->setSceneRect(0,0,960,230);
for (int i = 0; i < 50; i++)
{
Item *item = new Item();
item->setPos(item->boundingRect().width() * i, 0);
item->setAnimationSpeed(ui->horizontalSlider->value() / 10.0);
scene->addItem(item);
_items.append(item);
}
connect(timer, SIGNAL(timeout()), this, SLOT(timer_timeout()));
timer->start(1);
_elapsedTimer = new QElapsedTimer();
_elapsedTimer->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::timer_timeout()
{
if (_elapsedTimer->hasExpired(8))
{
_elapsedTimer->start();
ui->graphicsView->scene()->advance();
}
}
void MainWindow::on_horizontalSlider_valueChanged(int value)
{
foreach(Item *i, _items)
i->setAnimationSpeed(value / 10.0);
}
Re: Create a marquee with QGraphicsScene
Why are you using a 1ms timeout for your main QTimer? That is much too fast for any practical purposes. Typical video is 30 fps, which translates to a refresh period of 33 ms. Even at 33 ms, that is still too fast for your brain to see individual frames. If you item doesn't need to move that fast, then set a more realistic timeout.
What is your marquee being drawn on top of? Is it a mostly static image or is it a video? One way to avoid flicker is to avoid the need to refresh anything except the immediate region being drawn or to set a cache on the background image so it doesn't actually paint but simply bitblts the areas that are changed by the moving item.
Re: Create a marquee with QGraphicsScene
Hi,
I've tested with several intervals, but 16 or 33 are showing unacceptable flickering... I really don't know why is so unstable. I changed the code to use a QGraphicsItemAnimation and QTimeLine, and it looks more stable, but only with 1 ms interval is running smoothly.
I have no background, how should I configure the background cache?
Re: Create a marquee with QGraphicsScene
Have you tried using QGL::DoubleBuffer?
Re: Create a marquee with QGraphicsScene
Yes, I did it.
I also tried to do a simple animation with Qt Quick because some people tell me it's optimized for smooth transitions, but I get also a lot of "jumps" on the animation. Here is the code I used:
Code:
import QtQuick 1.1
Rectangle {
id: window
width: 960
height: 360
color: "#000000"
states : State {
name: "left"
PropertyChanges { target: item1; x: -962 }
}
MouseArea {
id: mouseArea
onClicked: if (window.state == '') window.state = "left"; else window.state = ''
anchors.fill: parent
anchors.margins: -5 // Make MouseArea bigger than the rectangle, itself
}
transitions: Transition {
NumberAnimation { properties: "x"; easing.type: Easing.Linear; duration: 4000 }
}
Item {
id: item1
x: 0
y: 274
width: 1923
height: 86
Item {
id: pos1
x: 0
y: 0
width: 960
height: 86
smooth: false
clip: false
Rectangle {
id: rectangle3
x: 0
y: 0
width: 960
height: 41
color: "#424242"
radius: 5
Text {
id: text3
x: 0
y: 0
width: 791
height: 41
color: "#ffffff"
text: qsTr("Some Text")
font.pixelSize: 40
font.family: "Helvetica"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
Rectangle {
id: rectangle4
x: 0
y: 45
width: 960
height: 41
color: "#424242"
radius: 5
Text {
id: text4
x: 0
y: 0
width: 791
height: 41
color: "#ffffff"
text: qsTr("Some Text")
font.family: "Helvetica"
font.pixelSize: 40
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
}
Item {
id: pos2
x: 962
y: 0
width: 959
height: 86
clip: false
smooth: false
Rectangle {
id: rectangle7
x: 0
y: 0
width: 960
height: 41
color: "#424242"
radius: 5
Text {
id: text7
x: 0
y: 0
width: 960
height: 41
color: "#ffffff"
text: qsTr("Some other text")
font.family: "Helvetica"
font.pixelSize: 40
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
Rectangle {
id: rectangle8
x: 0
y: 45
width: 960
height: 41
color: "#424242"
radius: 5
Text {
id: text8
x: 0
y: 0
width: 960
height: 41
color: "#ffffff"
text: qsTr("Some other text")
font.family: "Helvetica"
font.pixelSize: 40
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
}
}
}