第6章:DoubleBuffer

1,绘图双缓冲区

2,源码:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);


    this->setAutoFillBackground(true);                                             //对窗体背景的设置
    this->setPalette(QPalette(Qt::white));
    pix = new QPixmap(ui->centralWidget->size());                                  //此QPixmap对象用来准备随时接受绘制的内容
    pix->fill(Qt::white);                                                          //填充背景色为白色
    ui->centralWidget->setMinimumSize(600,400);                                    //设置绘制区窗体的最小尺寸

    creatToolBar();

    ShowStyle();

    this->setWidth(widthSpinBox->value());                                         //初始化线宽
    this->setColor(Qt::black);                                                     //初始化颜色
}

MainWindow::~MainWindow()
{
    delete ui;
}



//创建工具栏
void MainWindow::creatToolBar()
{
    styleLabel      = new QLabel(tr("线型风格:"));                   //创建线型风格控件
    styleComboBox   = new QComboBox;
    styleComboBox->addItem(tr("SloidLine"),      static_cast<int>(Qt::SolidLine));
    styleComboBox->addItem(tr("DashLine"),       static_cast<int>(Qt::DashLine));
    styleComboBox->addItem(tr("DotLine"),        static_cast<int>(Qt::DotLine));
    styleComboBox->addItem(tr("DashDotLine"),    static_cast<int>(Qt::DashDotLine));
    styleComboBox->addItem(tr("DashDotDotLine"), static_cast<int>(Qt::DashDotDotLine));
    connect(styleComboBox, SIGNAL(activated(int)), this, SLOT(setStyle(int)));


    widthLabel      = new QLabel(tr("线宽:"));
    widthSpinBox    = new QSpinBox;
    widthSpinBox->setValue(5);
    connect(widthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setWidth(int)));


    colorBtn = new QToolButton;
    QPixmap  pixmap(20,20);
    pixmap.fill(Qt::black);
    colorBtn->setIcon(QIcon(pixmap));
    connect(colorBtn, SIGNAL(clicked(bool)), this, SLOT(ShowColor()));


    clearBtn = new QToolButton;
    clearBtn->setText(tr("清除"));
    clearBtn->setMinimumSize(20, 20);
    connect(clearBtn, SIGNAL(clicked(bool)), this, SLOT(setClear()));


    ui->mainToolBar->addWidget(styleLabel);
    ui->mainToolBar->addWidget(styleComboBox);
    ui->mainToolBar->addWidget(widthLabel);
    ui->mainToolBar->addWidget(widthSpinBox);
    ui->mainToolBar->addWidget(colorBtn);
    ui->mainToolBar->addWidget(clearBtn);
}


//显示风格
void MainWindow::ShowStyle()
{
    this->setStyle(styleComboBox->itemData(styleComboBox->currentIndex(), Qt::UserRole).toInt());
}


//显示颜色
void MainWindow::ShowColor()
{
    QColor color = QColorDialog::getColor(static_cast<int>(Qt::black), this);

    if (color.isValid())
    {
        this->setColor(color);
        QPixmap p(20 ,20);
        p.fill(color);
        colorBtn->setIcon(QIcon(p));
    }
}



//设置风格
void MainWindow::setStyle(int s)
{
    style = s;
}


//设置字体宽度
void MainWindow::setWidth(int w)
{
    weight = w;
}


//设置颜色
void MainWindow::setColor(QColor c)
{
    color = c;
}


//清空
void MainWindow::setClear()
{
    QPixmap *clearPix = new QPixmap(ui->centralWidget->size());
    clearPix->fill(Qt::white);
    pix = clearPix;

    this->update();
}


//重新定义鼠标按下事件
void MainWindow::mousePressEvent(QMouseEvent *event)
{
    startPos = event->pos();
}



//鼠标移动事件
/*mouseTracking 属性指示窗体是否追踪鼠标,默认为false(不追踪)即在至少有一个鼠标按下的前提下移动鼠标才触发
  mouseMoveEvent()事件,可以通过setMouseTracking(bool enable方法对该属性值进行设置,如果为追踪,则无论是否
  有鼠标按键按下,只要鼠标移动,就会触发mouseMoveEvent()事件*/
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    QPainter *painter = new QPainter;                           //新建一个QPainter对象

    QPen pen;                                                   //新建一个QPen对象
    pen.setStyle((Qt::PenStyle)style);                          //设置画笔的线型
    pen.setWidth(weight);                                       //设置画笔的线宽值
    pen.setColor(color);                                        //设置画笔的颜色

    painter->begin(pix);                                        //相当于把painter绘制到图片中
    painter->setPen(pen);                                       //将QPen对象应用到绘制对象中
    painter->drawLine(startPos, event->pos());                  //绘制从startPos到鼠标当前位置的直线
    painter->end();
    startPos = event->pos();                                    //更新鼠标的当前位置,为下次绘制做准备

    //painter->begin(pix) painter->end();以QPixmap对象为QPainterDevice参数绘制,构造一个QPainter对象时,就立即
    //开始对绘画设备进行绘制,此构造QPainter对象是短期的,如应定义在QWidget::paintEvent()中,并只能调用一次,此构造函数
    //调用开始于begin()函数,并且在QPainter的析构函数中自动调用end()函数,由于当一个QPainter对象的初始化失败时gouz 函数
    //不能提供反馈信息,所以在绘制外部设备时应使用begin()和end(),如打印机等外围设备




    this->update();                                             //重绘绘制区窗体
}


//窗口大小调整事件
void MainWindow::resizeEvent(QResizeEvent *)
{
    if ((ui->centralWidget->height() > pix->height()) || (ui->centralWidget->width() > pix->width()))
    {
        QPixmap *newPix = new QPixmap(ui->centralWidget->size());

        newPix->fill(Qt::white);

        QPainter p(newPix);
        p.drawPixmap(QPoint(0, 0), *pix);
        pix = newPix;
    }
}





//重绘事件
void MainWindow::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    QPainter painter(this);

    painter.drawPixmap(QPoint(0, 0), *pix);
}

3,效果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ksmtnsv37297/article/details/86536466
今日推荐