1

I'll give you a minimal reproduceable example that was a part of the more complex widget. Here we just have a custom widget(called MovableItem) with a simple paintEvent. Widget is created, placed onto the central widget and moved to mouse position on MainWindow::mousePressEvent-s.

When moving, it seems like the widget is getting clipped at the side it's moving towards.

mainwindow.h
#include <QMainWindow>
#include <QMouseEvent>
#include <QPropertyAnimation>
#include "movableitem.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void mousePressEvent(QMouseEvent *event) override;

    QWidget* mItem;
};
mainwindow.cpp
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    resize(640, 480);
    QWidget* central_widget = new QWidget(this);
    mItem = new MovableItem(central_widget);
    mItem->move(20, 20);
    setCentralWidget(central_widget);
}

void MainWindow::mousePressEvent(QMouseEvent *event) {
    QPoint pos = event->pos();
    QPropertyAnimation* anim = new QPropertyAnimation(mItem, "geometry");
    anim->setDuration(750);
    anim->setStartValue(QRect(mItem->x(), mItem->y(), mItem->width(), mItem->height()));
    anim->setEndValue(QRect(pos.x(), pos.y(), mItem->width(), mItem->height()));
    anim->start();
}


MainWindow::~MainWindow() {}
movableitem.h
#include <QWidget>
#include <QPainter>
#include <QPainterPath>


class MovableItem : public QWidget
{
    Q_OBJECT
public:
    MovableItem(QWidget *parent = nullptr);
    QSize sizeHint() const override;
    void paintEvent(QPaintEvent *event) override;
};
movableitem.cpp
#include "movableitem.h"

MovableItem::MovableItem(QWidget *parent) : QWidget(parent)
{
    setParent(parent);
}


QSize MovableItem::sizeHint() const {
    return QSize(150, 40);
}

void MovableItem::paintEvent(QPaintEvent *event) {
    QRect r = rect();
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    QPainterPath path;
    path.addRoundedRect(r, 5, 5);

    QBrush brush(QColor(217, 217, 217));
    painter.fillPath(path, brush);

    painter.drawPath(path);
}

Example

enter image description here

As you can see, movement is not fluid, but choppy. I have no idea what is happening. Am I doing something completely wrong ? Do I need to implement some additional functions, is double buffering needed, is this because of Qt's automatic clipping ? Should I rewrite it in QGraphicsView ?

sup
  • 323
  • 1
  • 12
  • In your `paintEvent` try to add this `if (this->testAttribute(Qt::WA_WState_ConfigPending)) return;`. It will prevent widget's painting if it is still in process of painting. – Maxim Skvortsov Jun 23 '21 at 11:38

1 Answers1

0

Add mItem->repaint(); and mItem->update(); in mousePressEvent function

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    QPoint pos = event->pos();
    QPropertyAnimation* anim = new QPropertyAnimation(mItem, "geometry");
    anim->setDuration(750);
    anim->setStartValue(QRect(mItem->x(), mItem->y(), mItem->width(), mItem->height()));
    anim->setEndValue(QRect(pos.x(), pos.y(), mItem->width(), mItem->height()));
    anim->start();
    mItem->repaint();
    mItem->update();
}

my out put is here : Out put

Parisa.H.R
  • 3,303
  • 3
  • 19
  • 38