带有框架的 QGraphicsTextItem 的 QPropertyAnimation 会使文本抖动
QPropertyAnimation of a QGraphicsTextItem with a frame make the text shaky
我正在为一个QGraphicsTextItem
添加了一个框架。在动画过程中,文本似乎在框架内略微晃动,这非常烦人。
示例代码:
class MovingFrameText : public QGraphicsTextItem
{
Q_OBJECT;
public:
MovingFrameText( ) : QGraphicsTextItem(0)
{
setPlainText ( "human ");
QFont f = font();
f.setPixelSize(40);
setFont(f);
setFlags(QGraphicsItem::ItemIsMovable);
}
QRectF boundingRect() const
{
return QGraphicsTextItem::boundingRect().adjusted(-2,-2,+2,+2);
}
void paint(QPainter *painter,const QStyleOptionGraphicsItem *option,QWidget *widget)
{
QGraphicsTextItem::paint(painter,option,widget);
painter->setPen(Qt::black);
painter->drawRect(boundingRect());
}
};
int main(int argc, char *argv[])
{
QApplication app(argc,argv);
MovingFrameText t;
t.setPos(640,680);
QGraphicsScene scene;
scene.addItem(&t);
QGraphicsView view(&scene);
view.resize(640, 680);
view.show();
auto moveAnimation = new QPropertyAnimation( &t, "pos" );
moveAnimation->setDuration( 10000 );
moveAnimation->setStartValue( QPointF(640, 680) );
moveAnimation->setEndValue( QPointF(0, 0) );
moveAnimation->setEasingCurve( QEasingCurve::Linear );
moveAnimation->start(QAbstractAnimation::DeleteWhenStopped);
return app.exec();
}
有没有办法使动画平滑?
解决方案
您可以通过以下方式大幅改进动画:
- 使用
QVariantAnimation
而不是QPropertyAnimation
并在每次迭代中调用QGraphicsItem::update
- 使用附加
QPainter
缓冲绘画,并将QPixmap
作为画布进行所有绘画操作,然后使用传递给paint
方法的画家绘制画布
注意:QGraphicsTextItem
仍然会晃动一下,但至少它会表现为一个对象而不是几个独立的对象。
例
以下是我为您准备的示例,说明如何更改代码以实现建议的解决方案:
class MovingFrameText : public QGraphicsTextItem
{
public:
MovingFrameText(const QString &text, QGraphicsItem *parent = nullptr)
: QGraphicsTextItem(parent)
{
QFont f(font());
f.setPixelSize(40);
setFont(f);
setPlainText(text);
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->setClipping(true);
painter->setClipRect(option->rect);
painter->setRenderHint(QPainter::SmoothPixmapTransform);
QPixmap canvas(option->rect.size());
QPainter canvasPainter;
canvas.fill(Qt::transparent);
canvasPainter.begin(&canvas);
canvasPainter.setFont(font());
canvasPainter.drawRect(option->rect.adjusted(0, 0, -1, -1));
canvasPainter.drawText(option->rect, toPlainText());
painter->drawPixmap(0, 0, canvas);
}
};
int main(int argc, char *argv[])
{
QApplication app(argc,argv);
QGraphicsView view;
auto *t = new MovingFrameText("human");
view.setScene(new QGraphicsScene(&view));
view.setAlignment(Qt::AlignLeft | Qt::AlignTop);
view.setSceneRect(0, 0, 640, 680);
view.scene()->addItem(t);
view.show();
auto *moveAnimation = new QVariantAnimation();
moveAnimation->setDuration(10000);
moveAnimation->setStartValue(QPointF(640, 680));
moveAnimation->setEndValue(QPointF(0, 0));
moveAnimation->start(QAbstractAnimation::DeleteWhenStopped);
QObject::connect(moveAnimation, &QVariantAnimation::valueChanged, [t](const QVariant &value){
t->setPos(value.toPointF());
t->update();
});
return app.exec();
}
@scopchanov答案非常好。 我在这里添加了一个我也测试过的解决方案,并且似乎有效。我将需要更多时间来检查我认为哪个更好,但如果您以类似的问题结束,我会将其留在这里供其他人尝试。
class MovingFrameText : public QGraphicsTextItem
{
Q_PROPERTY( QPointF pos READ pos WRITE setPosition )
public:
void setPosition(QPointF pos)
{
setPos(floor(pos.x()+0.5),floor(pos.y()+.5) );
}
};
相关文章:
- 文本文件中的单词链表
- 从命令行c++发送文本文件名
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 2D数组来自文本输入,中间有空格
- 如何将内容数组写入文本文件?
- 无法通过空白将文本文件行分隔为矢量
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- C++将文本文件中的数据读取到结构数组中
- 在指针的帮助下,文本文件中单词的频率
- 将字符指针十六进制转换为字符串并保存在文本文件C++中
- 将值从二维数组输出到文本文件
- 如何在c++中从文本文件中逐行读取整数
- 如何创建一个QTableWidgetItem,用长文本右对齐,左边有省略号
- 从文本文件中读取时钟时间和事件时间并进行处理
- 如何从文本文件中读取值和数组
- 如何在C++中确定文本文件中的元素是字符还是数字
- 如何根据单词在文本中出现的概率输出单词
- 如何在C++中用std::cout正确显示带十六进制的字符串文本
- C++试图读取一个文件并输出到另一个文本文件
- 带有框架的 QGraphicsTextItem 的 QPropertyAnimation 会使文本抖动