Füllstandsanzeige mit Animation

Alles rund um die Programmierung mit Qt
Antworten
Ralle_91
Beiträge: 1
Registriert: 17. August 2018 09:45

Füllstandsanzeige mit Animation

Beitrag von Ralle_91 » 20. August 2018 15:43

Hallo,

ich versuche, eine Füllstandsanzeige zu entwerfen und bin am verzweifeln :( Die Füllstandsanzeige (animTest2.cpp) soll nachher aussehen, wie in der angehängten Zeichnung. Da ich große Probleme hatte das so umzusetzen, habe ich das Problem immer wieder in kleinere Teilprobleme aufgeteilt.

Nachher soll die Anzeige als Animation bei Mousemoves reagieren. Wenn die Maus nach oben gezogen wird, soll die selbst entworfene anzeige wie eine Scrollbar nach unten gezogen werden. Oben sollen dann neue Anzeigestriche entstehen. Ich hoffe mit dem Bild und der Erklärung ist das so verständlich ;)

Stand jetzt habe erstmal versucht eine Version umzusetzten, bei der mithilfe eines Timers die Füllstandsstriche nach oben verschoben werden. Sobald die Striche out of Bounds laufen sollten sie unten im Bild neu erscheinen. Allerdings funktioniert das nicht wie geplant, nicht alle Striche werden neu gezeichnet, manche verschwinden einfach.
Habt Ihr eine Idee Warum das so ist?

Mit welchem Ansatz baue ich am besten mein MouseEvent ein?
Das Event an sich ist nicht das Problem, aber ich habe kaum Erfahrung mit QT und kenne mich mit den Animationen überhaupt nicht aus :?

Vorab schon mal vielen Dank für eure Hilfe ;)

Code: Alles auswählen

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

    ui->setupUi(this);
   // ui->stackedWidget->insertWidget(0, &anTest);
   // ui->stackedWidget->setCurrentWidget(0);
    scene =new QGraphicsScene(this);
    ui->graphicsView->setScene(scene);
    ui->graphicsView->setRenderHint(QPainter::Antialiasing);

    scene->setSceneRect(-200,-300,300,600);

    QPen mypen = QPen(Qt::red);

    QLineF TopLine(scene->sceneRect().topLeft(), scene->sceneRect().topRight());
    QLineF LeftLine(scene->sceneRect().topLeft(), scene->sceneRect().bottomLeft());
    QLineF RightLine(scene->sceneRect().topRight(), scene->sceneRect().bottomRight());
    QLineF BottomLine(scene->sceneRect().bottomLeft(), scene->sceneRect().bottomRight());

    scene->addLine(TopLine,mypen);
    scene->addLine(LeftLine,mypen);
    scene->addLine(RightLine,mypen);
    scene->addLine(BottomLine,mypen);


    int ItemCount = 25;
    for(int i = 0; i < ItemCount; i++)
    {
        animTest2 *item = new animTest2(0, i*25);
        scene->addItem(item);
    }

    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), scene,SLOT(advance()));
    timer->start(100);
   
    }
    

Code: Alles auswählen

#ifndef ANIMTEST2_H
#define ANIMTEST2_H

#include <QPainter>
#include <QGraphicsItem>
#include <QGraphicsScene>

class animTest2 : public QGraphicsItem
{
public:
    animTest2(int x,int y);
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

protected:
    void advance(int phase);

private:
    qreal speed;
    void DoCollision();
};

#endif // ANIMTEST2_H

Code: Alles auswählen

#include "animtest2.h"

animTest2::animTest2(int x,int y)
{

    //random start rotation
       //set the speed
       speed = 2;

       //random start position
       int StartX = x;
       int StartY = y;

       setPos(mapToParent(StartX,StartY));
   }

   QRectF animTest2::boundingRect() const
   {
       return QRect(0,0,20,20);
   }

   void animTest2::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
   {
       QLine line(0,0,20,0);
       QBrush Brush(Qt::gray);
        painter->setBrush(Brush);
       //basic Collision detection
       if(scene()->collidingItems(this).isEmpty())
       {
           //no collision
       }
       else
       {
        //Set the position
           DoCollision();
       }
        painter->drawLine(line);
   }

   void animTest2::advance(int phase)
   {
       if(!phase) return;
       QPointF location = this->pos();
       setPos(mapToParent(0,-(speed)));
   }

   void animTest2::DoCollision()
   {
       //see if the new position is in bounds
       QPointF newpoint = mapToParent(0,400);
       //set the new position
       setPos(newpoint);
   }
Dateianhänge
Zeichnung_Fuellstand.png
Zeichnung_Fuellstand.png (13.67 KiB) 2608 mal betrachtet

solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Re: Füllstandsanzeige mit Animation

Beitrag von solarix » 8. September 2018 12:38

Mit dem Graphics-Framework kriegt man das vermutlich schon irgendwie hin, aber wenn ich dich wäre, würde ich das einfach schnell "Paintern":

Code: Alles auswählen

#include <QPainter>
#include "widget.h"
#include <QWheelEvent>

//------------------------------------------------------------------------------------------------------------
Widget::Widget()
 : mValue(2.8)
{
}

//------------------------------------------------------------------------------------------------------------
void Widget::paintEvent(QPaintEvent *)
{
    QPainter p(this);

    // ---------------- Skala
    static int min  = -50;
    static int max  = 50;
    static int step = 70; 

    p.save();
    p.translate(0,-50*step + height()/2); // "0" in die Mitte des Widgets
    p.translate(0,mValue*step);              // wir wollen nicht "0" in der Mitte haben, sondern den IST-Wert
    p.setPen(Qt::black);
    for (int i=max; i>min; i--) {              // Grosse Skala
        p.drawLine(0,0, 50, 0);
        p.drawText(70,0,QString("%1").arg(i));
        for (int j=0; j<9; j++) {                // kleine Skala (Zwischenschritte)
            p.translate(0,step/10);
            p.drawLine(0,0, 20, 0);
        }
        p.translate(0,step/10);
    }
    p.restore();

    // ---------------- Cursor
    p.save();
    p.translate(0,height()/2); // 0 in die Mitte des Widgets
    p.drawLine(30,0,40,-10);
    p.drawLine(30,0,40,+10);
    p.restore();

    // ---------------- Text
    QFont f = font();
    f.setPointSize(30);
    p.setFont(f);
    p.drawText(rect(),Qt::AlignCenter, QString("%1").arg(mValue));
}

//------------------------------------------------------------------------------------------------------------
void Widget::wheelEvent(QWheelEvent *e)
{
    mValue += e->delta()/300.0;
    update();
}


Antworten