PDA

View Full Version : Animate scale of QGraphicsObject upon selection with rubberband - not working



vgrunert
5th April 2015, 14:22
Hi,

I intend to create a custom scatterplot using the graphics view/scene/item framework.
I am stuck with adding a feature that animates the scale of a custom ellipse item if selected.
There should be two ways for selecting the item: by rubber band selection and/or by left mouse click.


I have two questions:



Why does the property animation not start if the:
animate function is in the constructor?
item is selected with the rubberband selection?


Please feel free to comment on the general structure (choises of classes or animation approach or for ex.) of the programm as well.
I am very new to Qt programming and still a bit overwhelmed by it.


Here is my code:



#ifndef MYELLIPSE_H
#define MYELLIPSE_H

#include <QPainter>
#include <QGraphicsObject>
#include <QPropertyAnimation>
#include <QGraphicsSceneMouseEvent>

#This class is a simple ellipse that should change it's color and start to animate it's scale once selected
#and stop if "unselected". It should be selectable with either a mousclick on it, or if in the rectangle of a rubberband.
#I chose the QGraphicsObject as the base class, because it works well with the
#QPropertAnmiation class
#I am aware of the QGraphicsItemAnimation, but it came to my attention that
#it became obsolete and is not supprted anymore.

class myEllipse : public QGraphicsObject
{
Q_OBJECT

public:

myEllipse(QRectF red): rect(rec)
{
setFlag(ItemIsSelectable, true);
setAcceptHoverEvents(true);
_hover = false;
_pressed = false;

#Does not work.
#However if I put the animate function into the
#mousePressedEvent it animates if I click with the mouse on it,
#but not if it's selected with the rubber band.
#What I don't understand is that since it changes it's color when selected with the
#rubberband why it does not start the animation.
if (this->isSelected()) {
animate();
}
#constructor end
}
~myEllipse(){}

QRectF boundingRect() const { return rect; }
void paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget) {

#This is working fine. Wheather I hover or click with the mouse over it
#or put it in the rectangle of a rubber band, it alsways changes it's color.
#Hence I assume that all three selection mode should be working.
if (isSelected() || _hover)
{
painter->setPen(Qt::darkGray);
} else {
painter->setPen(Qt::black);
}
painter->drawEllipse(rect);
}

protected:

#change color of pen if hover over
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *) { _hover = true; update(); }

#change color of pen back to black
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *) { _hover = false; update(); }

#select item and start animation
virtual void mousePressEvent(QGraphicsSceneMouseEvent *){
_pressed = true;
if (ev->MouseButtonPress)
{
setSelected(true);
#animate();
}

}
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *){ _pressed = false; update(); }

private:
QRectF rect;
bool _hover;
bool _pressed;
void animate(){
QPropertyAnimation *animation = new QPropertyAnimation(this, "scale");
animation->setDuration(1000);
animation->setStartValue(0.0);
animation->setEndValue(1.0);

animation->setLoopCount(10);
animation->start();
}
};

#endif // MYELLIPSE_H


And the mainWindow:



#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QGraphicsScene>
#include <QStandardItemModel>
#include <QStringList>
#include <QList>
#include "myellipse.h"

namespace Ui {
class MainWindow;
}

#The ui contains a tableView and a graphicsview item
class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0): QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setupModel();
ui->tableView->setModel(model);

myOtherScene = new QGraphicsScene(this);
ui->graphicsView_2->setDragMode(QGraphicsView::RubberBandDrag);
ui->graphicsView_2->setScene(myOtherScene);
setUpOtherScene();
}

~MainWindow();

private:
Ui::MainWindow *ui;
QStringList myList;
QAbstractItemModel *model;
QGraphicsScene *myOtherScene;

#Adds one custom graphics item from a standartitem model to the scene
void setUpOtherScene(){

int row = 0;
myEllipse *ellipse = new myEllipse(QRectF(-10*(model->data(model->index(row,1)).toDouble()),
-10*(model->data(model->index(row,2)).toDouble()),
15, 15));
myOtherScene->addItem(ellipse);
}
#Create a table with Four categories (A,B,C,D) in the first column and random ints from 1 to 10
#in the second and third column.
void setupModel(){
myList << "A" << "B" << "C" << "D";
model = new QStandardItemModel(4,3,this);

for (int row = 0; row < model->rowCount(QModelIndex()); ++row) {
model->setData(model->index(row, 0, QModelIndex()),
myList[row]);
model->setData(model->index(row, 1, QModelIndex()),
qrand()%10);
model->setData(model->index(row, 2, QModelIndex()),
qrand()%10);
}
}

};

#endif // MAINWINDOW_H



I tried to get this working for days now, with some success but I need some help to make it over the finish line.
Thank you many times.