QGraphicsView的paintEvent双缓存绘画

MyGraphicsView.h

 1 #ifndef MYGRAPHICSVIEW_H
 2 #define MYGRAPHICSVIEW_H
 3
 4 #include <QGraphicsView>
 5 #include <QMouseEvent>
 6 #include <QPaintEvent>
 7 #include <QKeyEvent>
 8 #include <QPainter>
 9 #include <QPixmap>
10 #include <QDebug>
11
12 class MyGraphicsView : public QGraphicsView
13 {
14     Q_OBJECT
15
16 public:
17     MyGraphicsView(QWidget *parent);
18     ~MyGraphicsView();
19
20 protected:
21     void mousePressEvent(QMouseEvent *event);
22     void mouseDoubleClickEvent(QMouseEvent *event);
23     void mouseMoveEvent(QMouseEvent *event);
24     void mouseReleaseEvent(QMouseEvent *event);
25     void paintEvent(QPaintEvent *event);
26     void keyPressEvent(QKeyEvent *event);
27
28 private:
29     QPixmap pix;
30     QPoint lasetPoint;
31     QPoint endPoint;
32     QPixmap tempPix;
33     bool isDrawing;
34     bool isDoubleClick;
35 };
36
37 #endif // MYGRAPHICSVIEW_H

MyGraphicsView.cpp

#include "MyGraphicsView.h"

MyGraphicsView::MyGraphicsView(QWidget *parent)
    : QGraphicsView(parent)
{
    pix = QPixmap(1024, 768);
    pix.fill(Qt::white);
    isDrawing = false;
    isDoubleClick = false;
}

MyGraphicsView::~MyGraphicsView()
{

}

void MyGraphicsView::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        lasetPoint = event->pos();
        isDrawing = true;
        isDoubleClick = false;
    }

    QGraphicsView::mousePressEvent(event);
}

void MyGraphicsView::mouseDoubleClickEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        isDoubleClick = true;
    }

    QGraphicsView::mouseDoubleClickEvent(event);
}

void MyGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton)
    {
        if (!isDoubleClick)
        {
            endPoint = event->pos();
            this->viewport()->update();
        }
    }

    QGraphicsView::mouseMoveEvent(event);
}

void MyGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        if (!isDoubleClick)
        {
            endPoint = event->pos();
            isDrawing = false;
            this->viewport()->update();
        }
    }

    QGraphicsView::mouseReleaseEvent(event);
}

void MyGraphicsView::paintEvent(QPaintEvent *event)
{
    /// 直接在窗体上绘图,前1次画的矩形是不能保存住的
//     QPainter painter(this->viewport());
//     int x, y, w, h;
//     x = lasetPoint.x();
//     y = lasetPoint.y();
//     w = endPoint.x() - x;
//     h = endPoint.y() - y;
//     painter.drawRect(x, y, w, h);

    /// 直接在pix上绘图,前1次前2次前3次...画的都保存住了(鼠标每移动一点就会触发paintEvent函数而画一次),所以在pix上会呈现好多矩形
//     int x, y, w, h;
//     x = lasetPoint.x();
//     y = lasetPoint.y();
//     w = endPoint.x() - x;
//     h = endPoint.y() - y;
//     QPainter pp(&pix);
//     pp.drawRect(x, y, w, h);
//     QPainter painter(this->viewport());
//     painter.drawPixmap(0, 0, pix);

    /// 双缓冲绘图,原理是在拖动过程中先把原来的图形复制到tempPix里面并在tempPix里面画,我们此时看到的就是在tempPix里的图形。只在鼠标释放的时候才在pix绘一次。
    int x, y, w, h;
    x = lasetPoint.x();
    y = lasetPoint.y();
    w = endPoint.x() - x;
    h = endPoint.y() - y;

    QPainter painter(this->viewport());
    if (isDrawing)
    {
        tempPix = pix;
        QPainter pp(&tempPix);
        pp.drawRect(x, y, w, h);
        painter.drawPixmap(0, 0, tempPix);
    }
    else
    {
        QPainter pp(&pix);
        pp.drawRect(x, y, w, h);
        painter.drawPixmap(0, 0, pix);
    }

    QGraphicsView::paintEvent(event);
}

void MyGraphicsView::keyPressEvent(QKeyEvent *event)
{
    QGraphicsView::keyPressEvent(event);
}

三种绘制方法效果图:

时间: 2024-10-10 02:28:07

QGraphicsView的paintEvent双缓存绘画的相关文章

Android 框架修炼-自己封装双缓存管理框架库

一.概述 Android开发中,网络请求是很重要的一部分,而缓存网络请求来的图片或者响应结果字符串或者结果流,既可以省流量,同时也可以帮助我们 解决无网或弱网情况下加载情况,当然也可以提升程序性能效率.纵所周知,缓存管理中肯定需要用到内存缓存,这里我们采用LruCache来管理内存的缓存. LruCahce虽然速度快,但是只是内存级别的缓存,为了实现持久化的缓存,我们还需要文件级别的缓存,也就是说我们要把缓存保存到文件,而文件则是保存 到手机存储或者SD卡存储中,即实现Disk级别的缓存,这里我

GDI+ 双缓存 和 刷新桌面(F5)

GDI+双缓存 POINT currentPoint; GetCursorPos(&currentPoint); HWND hWnd = ::GetDesktopWindow(); int nWidth = GetSystemMetrics(SM_CXSCREEN); int nHeight = GetSystemMetrics(SM_CYSCREEN); RECT r; GetWindowRect(hWnd, &r); Bitmap bmp(nWidth, nHeight); Graph

Android中用双缓存技术,加载网络图片

最近在学校参加一个比赛,写的一个Android应用,里面要加载大量的网络图片,可是用传统的方法图片一多就会造成程序出现内存溢出而崩溃.因为自己也在学习中,所以看了很多博客和视频,然后参照这些大神的写源码,自己写了一个加载网络图片工具类. 里面要用到一个经典的图片缓存库DiskLruCache 下载地址为:  DiskLruCache下载 下面是使用这个类实现的 双缓存网络图片加载 [java] view plain copy public class DiskLruCacheUtils { pr

关于双缓存

为了防止屏幕闪烁现象,利用双缓存解决.原理主要是将图片画在虚拟屏幕上,再将画直接从虚拟屏幕上直接画在实际屏幕上.repaint()方法实际上是先调用update()方法然后再调用paint()方法,实现双缓存就利用了这一点,代码如下 Image offScreenImage=null; public void update(Graphics g)       {         if(offScreenImage==null)             offScreenImage=this.cr

android listview 异步加载图片并防止错位+双缓存

网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertView 但没有异步操作也不会有问题. 我简单分析一下: 当重用 convertView 时,最初一屏显示 7 条记录, getView 被调用 7 次,创建了 7 个 convertView. 当 Item1 划出屏幕, Item8 进入屏幕时,这时没有为 Item8 创建新的 view 实例, Ite

Android性能优化之实现双缓存的图片异步加载工具(LruCache+SoftReference) - 拿来即用

之前在郭大神的博客看到使用LruCache算法实现图片缓存的.这里仿效他的思路,自己也写了一个. 并加入ConcurrentHashMap<String, SoftReference<Bitmap>>去实现二级缓存,因为ConcurrentHashMap是多个锁的线程安全,支持高并发.很适合这种频繁访问读取内存的操作. 下面整个思路是,使用了系统提供的LruCache类做一级缓存, 大小为运行内存的1/8,当LruCache容量要满的时候,会自动将系统移除的图片放到二级缓存中,但为

7_DoubleBuffer 游戏编程中的双缓存模式

### double buffer 双缓存 简单说: 当一个缓存被读取的时候,往另一个缓存里写入, 如此交替 #### the pattern 有两个缓存实例,一个是 current buffer, 一个是next buffer 从current buffer读取信息, 往next buffer里写入信息. swap操作,进行两种buff的身份切换 #### 何时使用 1 需要增量修改的状态 2 在修改的过程中需要进行访问 3 当访问数据的时候,不会发现数据正在被写入 4 读操作不用等待写的操作

双缓存显示问题以及图片

void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { if (!pdc) return; CClientDC dc(this); CRect rect; GetClientRect(rect); CDC MemDC; MemDC.CreateCompatibleDC(&dc); CBitmap MemBitmap; if(GetFileAttributes(m_strFileName) == I

双缓存静态循环队列(三)

1 // TwoBufQueue.h: interface for the CTwoBufQueue class. 2 // 3 ////////////////////////////////////////////////////////////////////// 4 5 #if !defined(AFX_TWOBUFQUEUE_H__EA19608F_9562_4803_95C4_5C4A574CC928__INCLUDED_) 6 #define AFX_TWOBUFQUEUE_H__