Qt学习10:像丝一样滑(双缓冲)

 
void CannonField::paintEvent(QPaintEvent *e)
{
	// -------------------------------------
	// QPaintEvent包含一个必须被刷新的窗口部件的区域
    // QPainter默认只能在paintEvent里面调用
	// -------------------------------------
	QRect cr = cannonRect();

	// --------------------------------------
	// 只要有一个象素相交,就返回true。
	// --------------------------------------
	if (!e->rect().intersects(cr))
	{
        return;
	}

	QPixmap pix(cr.size());
	//用this的背景色填充The QPoint offset 
	//defines a point in widget coordinates 
	//to which the pixmap's top-left pixel will be mapped to.
	pix.fill(this, cr.topLeft());

	//先绘到QPixmap上,再把QPixmap贴到this.
	QPainter p(&pix);

	//图片设为蓝色
	p.setBrush(Qt::blue);
	p.setPen(Qt::PenStyle::NoPen);

	//这个移的是坐标系,相当于QRect在做所有的运算时,
	//都先要offerset(-0, -pix.height()   
	p.translate(0, pix.height());

	p.drawPie(QRect(-35, -35, 70, 70), 0, 90*16);

	//rotate是旋轩坐标系.顺时针方向为正,逆时针为负.
	p.rotate(-ang);
	p.drawRect(QRect(33, -8, 15, 8));
	//Ends painting. Any resources used while painting are released. 
	p.end();

	//only one painter at a time
	p.begin(this);
	p.drawPixmap(cr.topLeft(), pix);
}

右下角绘制:

void CannonField::paintEvent(QPaintEvent *e)
{
	// -------------------------------------
	// QPaintEvent包含一个必须被刷新的窗口部件的区域
    // QPainter默认只能在paintEvent里面调用
	// -------------------------------------
	QRect cr = cannonRect();

	// --------------------------------------
	// 只要有一个象素相交,就返回true。
	// --------------------------------------
	if (!e->rect().intersects(cr))
	{
        return;
	}

	QPixmap pix(cr.size());
	//用this的背景色填充The QPoint offset 
	//defines a point in widget coordinates 
	//to which the pixmap's top-left pixel will be mapped to.
	pix.fill(this, cr.topLeft());

	//先绘到QPixmap上,再把QPixmap贴到this.
	QPainter p(&pix);

	//图片设为蓝色
	p.setBrush(Qt::blue);
	p.setPen(Qt::PenStyle::NoPen);

	//这个移的是坐标系,相当于QRect在做所有的运算时,
	//都先要offerset(-0, -pix.height()   
	//p.translate(0, pix.height());

	//p.drawPie(QRect(-35, -35, 70, 70), 0, 90*16);
	p.translate(pix.width(), pix.height());
	p.drawPie(QRect(-35, -35, 70, 70), 90*16, 90*16);
	//p.drawRect(QRect(-35, -35, 70, 70));

	//rotate是旋轩坐标系.顺时针方向为正,逆时针为负.
	p.rotate(ang);
	p.drawRect(QRect(-33-15, -8, 15, 8));
	//Ends painting. Any resources used while painting are released. 
	p.end();

	//only one painter at a time
	p.begin(this);
	p.drawPixmap(cr.topLeft(), pix);
}



1.先画到临时的pix上,再一次绘出来,双缓冲

2.drawPie的起始角度不要忘了*16,还有它是以逆时针旋转算角度的

 

转载于:https://www.cnblogs.com/hgy413/archive/2011/12/18/3693565.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Qt C++ 中使用双缓冲技术进行绘图,可以按照以下步骤进行操作: 1. 创建一个自定义的 QWidget 子类,例如 MyPaintWidget,用于绘制图形。 ```cpp class MyPaintWidget : public QWidget { Q_OBJECT public: explicit MyPaintWidget(QWidget *parent = nullptr); protected: void paintEvent(QPaintEvent *event) override; private: QImage buffer; // 双缓冲区 }; MyPaintWidget::MyPaintWidget(QWidget *parent) : QWidget(parent) { // 设置窗口属性,启用双缓冲绘制 setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_NoSystemBackground); } void MyPaintWidget::paintEvent(QPaintEvent *event) { // 创建绘图对象,并将其绑定到双缓冲区 QPainter painter(&buffer); // 在双缓冲区上进行绘制 painter.fillRect(rect(), Qt::white); // 绘制白色背景 painter.setPen(Qt::black); // 设置画笔颜色为黑色 painter.drawLine(0, 0, width(), height()); // 绘制一条线段 // 将双缓冲区的内容绘制到窗口上 painter.begin(this); painter.drawImage(0, 0, buffer); painter.end(); } ``` 2. 在主窗口的构造函数中创建 MyPaintWidget 对象,并将其添加到布局中。 ```cpp MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { MyPaintWidget *paintWidget = new MyPaintWidget(this); setCentralWidget(paintWidget); } ``` 通过以上步骤,我们创建了一个自定义的 QWidget 子类,并在其中实现了双缓冲绘图的功能。在 paintEvent 函数中,首先将绘图操作绘制在双缓冲区(buffer)上,然后再将双缓冲区的内容绘制到窗口上。这样可以避免图形闪烁的问题,并提高绘图的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值