15、自定义绘制图形(双缓冲机制)

发布时间 2023-12-11 15:06:27作者: 秃头的C#

效果图

 

//drawwidget.h
#ifndef DRAWWIDGET_H
#define DRAWWIDGET_H

#include <QObject>
#include <QWidget>

#include <QtGui>
#include <QMouseEvent> //鼠标事件
#include <QPaintEvent> //绘制事件
#include <QResizeEvent> //实时获取窗口操作等的大小
#include <QColor> //提供选择颜色的
#include <QPixmap> //显示图像
#include <QPainter> //绘制图形相关
#include <QPalette>
#include <QPen> //画笔


class DrawWidget : public QWidget
{
    Q_OBJECT
public:
    explicit DrawWidget(QWidget *parent = nullptr);

    void mousePressEvent(QMouseEvent *); //关联鼠标相关操作
    void mouseMoveEvent(QMouseEvent *);
    void paintEvent(QPaintEvent *);
    void resizeEvent(QResizeEvent *);

signals:

public slots:
    void setStyle(int); //设置风格
    void setWidth(int); //设置线的宽度
    void setColor(QColor); //设置线的颜色
    void clearFunc(); // 清除信息

private:
    QPixmap *pix; // 在屏幕上显示图像而设计和优化
    QPoint  startpos; //起始点
    QPoint endpos; //结束点
    int style,widthss;
    QColor color;
};

#endif // DRAWWIDGET_H
//drawwidget.cpp
#include "drawwidget.h"
#include <QDebug>

DrawWidget::DrawWidget(QWidget *parent) : QWidget(parent)
{
    setAutoFillBackground(true);
    setPalette(QPalette(Qt::white));
    pix=new QPixmap(size());
    pix->fill(Qt::white);

    //设置绘制区域窗体最小尺寸
    setMinimumSize(600,400);

}


//mousePressEvent 用于鼠标按下事件
void DrawWidget::mousePressEvent(QMouseEvent *e)
{
    startpos=e->pos();
}

//用于处理鼠标移动事件
void DrawWidget::mouseMoveEvent(QMouseEvent *e)
{
    QPainter *painter= new QPainter;
    QPen pen;
    pen.setStyle((Qt::PenStyle)style);
    pen.setWidth(widthss);
    pen.setColor(color);

    painter->begin(pix);
    painter->setPen(pen);
    painter->drawLine(startpos,e->pos());
    painter->end();

    startpos=e->pos();
    qDebug() << "移动";
    update();
}

//用于处理绘图事件
void DrawWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.drawPixmap(QPoint(0,0),*pix);
}

void DrawWidget::resizeEvent(QResizeEvent *event)
{
    if(height()>pix->height() || width()>pix->width()){
        QPixmap *newPix=new QPixmap(size());

        newPix->fill(Qt::white);

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

    }
    QWidget::resizeEvent(event);
}

void DrawWidget::setStyle(int s)
{
    style=s;
}

void DrawWidget::setWidth(int w)
{
    widthss=w;
}

void DrawWidget::setColor(QColor c)
{
    color=c;
}

void DrawWidget::clearFunc()
{
    QPixmap *cPix=new QPixmap(size());
    cPix->fill(Qt::white);
    pix=cPix;
    update();
}
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include "drawwidget.h"
#include <QLabel>
#include <QComboBox>
#include <QToolButton>
#include <QSpinBox>

#include <QGridLayout>
#include <QColorDialog>
#include <QToolBar>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

    void CreateToolBarFunc();


private:
    DrawWidget *drawWidget;

    QGridLayout *glayout;

    QLabel *labelStyle;
    QComboBox *comboboxStyle;

    QLabel *labelWidth;
    QSpinBox *labelWidthSpinBox;

    QToolButton *colorButton;
    QToolButton *clearButton;

private slots:
    void dispStyle();
    void dispColor();

};

#endif // MAINWINDOW_H
//mainwindow.cpp
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setWindowTitle("自定义绘图(双缓冲机制)");

    drawWidget = new DrawWidget;

    setCentralWidget(drawWidget);//将刚才创建对象作为主窗口的中心窗口

    CreateToolBarFunc();//调用次函数实现创建工具栏

    setMinimumSize(600,400);

    dispStyle();

    drawWidget->setWidth(labelWidthSpinBox->value());//初始化线的宽度
    drawWidget->setColor(Qt::blue); //初始化线的颜色

}

MainWindow::~MainWindow()
{

}

void MainWindow::CreateToolBarFunc() //创建工具条
{
    QToolBar *toolBar = addToolBar("Tool");
    labelStyle = new QLabel("线型风格:");
    comboboxStyle=new QComboBox;
    comboboxStyle->addItem("SolidLine",static_cast<int>(Qt::SolidLine));
    comboboxStyle->addItem("DashLine", static_cast<int>(Qt::DashLine));
    comboboxStyle->addItem("DotLine", static_cast<int>(Qt::DotLine));
    comboboxStyle->addItem("DashDotLine", static_cast<int>(Qt::DashDotLine));
    comboboxStyle->addItem("DashDotDotLine", static_cast<int>(Qt::DashDotDotLine));

    connect(comboboxStyle,SIGNAL(activated(int)),this,SLOT(dispStyle()));


    labelWidth=new QLabel("宽度:");
    labelWidthSpinBox=new QSpinBox;
    connect(labelWidthSpinBox,SIGNAL(valueChanged(int)),drawWidget,SLOT(setWidth(int)));

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

    clearButton=new QToolButton;
    clearButton->setText("清除绘制");
    connect(clearButton,SIGNAL(clicked()),drawWidget,SLOT(clearFunc()));

    toolBar->addWidget(labelStyle);
    toolBar->addWidget(comboboxStyle);
    toolBar->addWidget(labelWidth);
    toolBar->addWidget(labelWidthSpinBox);
    toolBar->addWidget(colorButton);
    toolBar->addWidget(clearButton);
}

void MainWindow::dispStyle()
{
    drawWidget->setStyle(comboboxStyle->itemData(comboboxStyle->currentIndex(),Qt::UserRole).toInt());

}

void MainWindow::dispColor()
{
    QColor color=QColorDialog::getColor(static_cast<int>(Qt::black),this);
    if(color.isValid()){
        drawWidget->setColor(color);
        QPixmap ps(20,20);
        ps.fill(color);
        colorButton->setIcon(ps);
    }
}