问题描述
我会给你一个最小的可复制示例,它是更复杂的小部件的一部分。
这里我们只有一个带有简单 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);
}
示例
如您所见,运动不是流畅的,而是断断续续的。我不知道发生了什么。我做错了什么吗?我是否需要实现一些附加功能,是否需要双缓冲,这是因为 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();
}