自定义小部件在移动时闪烁和剪切

问题描述

我会给你一个最小的可复制示例,它是更复杂的小部件的一部分。 这里我们只有一个带有简单 MovableItem自定义小部件(称为 paintEvent)。小部件被创建,放置在中央小部件上并移动到 MainWindow::mousepressEvent-s 上的鼠标位置。

移动时,小部件似乎在其移动的一侧被夹住了。

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->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);
}

示例

enter image description here

如您所见,运动不是流畅的,而是断断续续的。我不知道发生了什么。我做错了什么吗?我是否需要实现一些附加功能,是否需要双缓冲,这是因为 Qt's automatic clipping 吗?我应该在 QGraphicsView 中重写它吗?

解决方法

在 mousePressEvent 函数中添加 mItem->repaint(); mItem->update();

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->height()));
    anim->start();
    mItem->repaint();
    mItem->update();
}

我的输出在这里:Out put