Qt第四天总结(QPainter基础绘图)

一些问题:

  1. 在Qt编译好之后运行程序时提示:程序异常结束。The process was ended forcefully. …exe crashed.:通常情况是空指针或者数组越界问题,少数情况也有自己少写或者多写了一些无效或重复的代码而引起。

一些知识点:

  1. 建一个主窗口,在其中加入所需控件及设置绘图区域:
    QLabel * SharpLabel = new QLabel("形状:",this);//显示为“形状:”的标签
 	shapeCombobox=new QComboBox(this);//形状复合箱
  	SharpLabel->setGeometry(430,20,60,40);// 从屏幕上(430,20)位置开始(即为从最左上角的点),显示一个60*40的界面(宽60,高40)
  
  	//给形状复合箱中加入元素
    shapeComboBox->setGeometry(500,20,150,40); 从屏幕上(500,20)位置开始(即为从最左上角的点开始),显示一个150*40的界面(宽150,高40)
    shapeComboBox->addItem("Line",PaintArea::Line);
    shapeComboBox->addItem("Rectangle",PaintArea::Rectangle);
    shapeComboBox->addItem("RoundRect",PaintArea::RoundRect);
    shapeComboBox->addItem("Ellipse", PaintArea::Ellipse);
    shapeComboBox->addItem("Path", PaintArea::Path);
    shapeComboBox->addItem("Polyline", PaintArea::Polyline);
    shapeComboBox->addItem("Arc", PaintArea::Arc);
    shapeComboBox->addItem("Points", PaintArea::Points);
    shapeComboBox->addItem("Text", PaintArea::Text);

	//加入画笔、画刷、线宽
	
	QLabel * PenColorLabel = new QLabel("画笔颜色:",this);//画笔标签
    PenColorLabel->setGeometry(430,90,60,40);//标签大小
    //画笔颜色修改框
    colorFrame = new QFrame(this);
    colorFrame->setGeometry(500,90,150,40);
    colorFrame->setAutoFillBackground(true);
    colorFrame->setPalette(QPalette(Qt::blue));
    //画笔颜色修改按钮
    QPushButton *colorPushButton = new QPushButton("修改",this);
    colorPushButton->setGeometry(650,90,50,40);
    
    QLabel * BrushColorLabel = new QLabel("画刷颜色:",this);//画刷标签
    BrushColorLabel->setGeometry(430,160,60,40);
    //画刷颜色修改框
    brushColorFrame = new QFrame(this);
    brushColorFrame->setGeometry(500,160,150,40);
    brushColorFrame->setAutoFillBackground(true);
    brushColorFrame->setPalette(QPalette(Qt::blue));
    //画刷颜色修改按钮
    QPushButton *brushcolorPushButton = new QPushButton("修改",this);
    brushcolorPushButton->setGeometry(650,160,50,40);
  
    QLabel * LineWidthLabel = new QLabel("线宽:",this);//线宽标签
    LineWidthLabel->setGeometry(430,250,60,40);
    widthSpinBox = new QSpinBox(this);
    widthSpinBox->setGeometry(500,250,60,40);
    //线宽调整范围
    widthSpinBox->setRange(0,20); 


	paintArea = new PaintArea(this);
    //设置绘图区域窗口大小及位置
    paintArea->setGeometry(0,0,400,400);

  • 绘图区域另设类与函数
  1. 在widget头文件中加槽函数:分别与形状、画笔、画刷、线宽对应,并在.cpp中实现connect():
public slots:
    //修改形状槽函数
    void slotShape(int);
    //修改画笔槽函数
    void slotPenColor();
    //修改笔宽槽函数
    void slotPenWidth(int);
    //修改画刷槽函数
	void slotBrushColor(); 

connect(shapeComboBox,SIGNAL(activated(int)),this,SLOT(slotShape(int)));   
connect(colorPushButton,SIGNAL(clicked()),this,SLOT(slotPenColor()));//点击实现修改画笔颜色
connect(brushcolorPushButton,SIGNAL(clicked()),this,SLOT(slotBrushColor()));//点击修改画刷颜色
connect(widthSpinBox,SIGNAL(valueChanged(int)),this,SLOT(slotPenWidth(int)));//线宽数值改变则画笔宽度改变

  • activated(int):当用户选则ComboBox中的Item时,将会产生一个选中Item序号值的消息信号,不管选项是够改变都会产生该消息。(也有activated(QString))
  • 对比currentIndexChanged (int):当前ComboBox中的CurrentIndex改变时,不管是交互式还是通过程序改变选项,都会产生一个改变值得消息信号,如果ComboBox为空或重置当前ComboBox,产生的消息值返回-1。
  • 重点是currentIndexChanged不管是交互式(通过鼠标点击切换)还是通过程序改变选项,都会产生一个改变值的消息信号
    此对比源自QComboBox中activated信号与currentIndexChanged信号的区别

3.类PaintArea中 设置形状菜单,形状、画笔、笔刷、绘图事件的函数定义。并在paintarea.cpp中实现。

public:
enum Shape
 {Line,Rectangle,RoundRect,Ellipse,Polygon,Polyline,Points,Arc,Path,Text,Pixmap};
public:
    explicit PaintArea(QWidget *parent = 0);
public:
    void setShape(Shape s);
    void setPen(QPen  p);
    void setBrush(QBrush b);
    void paintEvent(QPaintEvent *);
private:
    Shape shape;
    QBrush brush;
    QPen pen; 

void PaintArea::setShape(Shape s)
{
    shape = s;
    update();
}
 
void PaintArea::setBrush(QBrush b)
{
    brush = b;
    update();
}  

void PaintArea::setPen(QPen p)
{
    pen = p;
    update();
}

void PaintArea::paintEvent(QPaintEvent *)
{
    QPainter p(this);//指定画家对象p
    p.setPen(pen);//p中设置画笔
    p.setBrush(brush);//p中设置画刷
    QRect rect(50,100,300,200);//设定一个长方形区域
    static const QPoint points[4] = {创建一个QPoint的数组,包含四个点,为画多边形,多边线及点做准备
        QPoint(150,100),
        QPoint(300,150),
        QPoint(350,250),
        QPoint(100,300)
    };

    int startAngle = 30 * 16;//设置弧线的起始角度
    int spanAngle = 120 * 16;//设置弧线的结束角度

    QPainterPath path; //新建一个QPainterPath对象为画路径做准备
    path.addRect(150,150,100,100);//x, y, w, h
    path.moveTo(100,100);  //将坐标移动到(100 100)位置
    
    //绘制贝塞尔曲线
    path.cubicTo(300,100,200,200,300,300);
    path.cubicTo(100,300,200,200,100,100);

	//选择不同形状,实现不同效果
    switch(shape)
    {
        case Line:
            p.drawLine(rect.topLeft(),rect.bottomRight());//获得矩形左上、右下角位置
            break;
        case Rectangle:
            p.drawRect(rect);
            break;
        case RoundRect:
            p.drawRoundRect(rect);
            break;
        case Ellipse:
            p.drawEllipse(rect);
            break;
        case Polygon:
            p.drawPolygon(points,4);
            break;
        case Polyline:
            p.drawPolyline(points,4);
            break;
        case Points:
            p.drawPoints(points,4);
            break;
        case Arc:
            p.drawArc(rect,startAngle,spanAngle);
            break;
        case Path:
            p.drawPath(path);
            break;
        case Text:
            p.drawText(rect,Qt::AlignCenter,tr("Hello Qt"));
            break;
        default:
            break;
    }
}

  • update():随即触发重绘,根据新数据重绘,若没有则新的图样不会显示。
  1. 绘图区域背景设置与函数实现:

	//设置背景白色
    QPalette pal = palette();//调色板类变量
    pal.setColor(QPalette::Background, Qt::white);//设置此变量颜色:背景,白色
    setAutoFillBackground(true);//设置好后自动填充背景色
    setPalette(pal);//显示颜色
    shape = Line;//形状默认为:线

	void Widget::slotShape(int value)
	{
    PaintArea::Shape shape = PaintArea::Shape(shapeComboBox->itemData(value,Qt::UserRole).toInt());//itemData得到一个元素数据(形状)是QString类型的,将其转换成整型赋给shape变量
    paintArea->setShape(shape);//在绘图区域显示形状(setShape()参数为整型)
	}
 
	void Widget::slotPenColor()
	{
    QColor color = QColorDialog::getColor(Qt::blue);
    colorFrame->setPalette(QPalette(color));
    int width = widthSpinBox->value();
    Qt::PenStyle style = Qt::SolidLine;
    Qt::PenCapStyle cap = Qt::RoundCap;
    Qt::PenJoinStyle join = Qt::RoundJoin;
    paintArea->setPen(QPen(color, width, style, cap, join));//显示画笔,颜色、宽度、样式、渐变以及纹理
	}

	void Widget::slotBrushColor()
	{
    QColor color = QColorDialog::getColor(Qt::blue);
    brushColorFrame->setPalette(QPalette(color));
    paintArea->setBrush(QBrush(color));
	}

	void Widget::slotPenWidth(int value )
	{
    QColor color = colorFrame->palette().color(QPalette::Window);
    Qt::PenStyle style = Qt::SolidLine;
    Qt::PenCapStyle cap = Qt::RoundCap;
    Qt::PenJoinStyle join = Qt::RoundJoin;
    paintArea->setPen(QPen(color, value, style, cap, join));
	}

  • setData():可以单独存储用户数据,使用Qt::UserRole、Qt::UserRole + 1……

完整纯代码实现:

//paintarea.h
#ifndef PAINTAREA_H
#define PAINTAREA_H

#include <QMainWindow>
#include <QObject>
#include <QWidget>
#include <QPen>
#include <QBrush>


class PaintArea : public QWidget
{
    Q_OBJECT

public:
    enum Shape{
        Line,Rectangle,RoundRect,Ellipse,Polygon,Polyline,Points,Arc,Path,Text,Pixmap
    };

public:
    explicit PaintArea(QWidget *parent = nullptr);

public:
    void setShape(Shape s);
    void setPen(QPen p);
    void setBrush(QBrush b);
    void paintEvent(QPaintEvent *);


private:
    Shape shape;
    QBrush brush;
    QPen pen;
    PaintArea *paintArea;
};

#endif // PAINTAREA_H

//widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QLabel>
#include <QComboBox>
#include <QFrame>
#include <QPushButton>
#include <QSpinBox>
#include <paintarea.h>


class Widget : public QWidget
{
    Q_OBJECT

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

public slots:
    //修改形状槽函数
    void slotShape(int);
    //修改画笔槽函数
    void slotPenColor();
    //修改笔宽槽函数
    void slotPenWidth(int);
    //修改画刷槽函数
void slotBrushColor();

private:

    QLabel *SharpLabel;
    QComboBox *shapeComboBox;
    QLabel *PenColorLabel;
    QFrame *colorFrame;
    QPushButton *colorPushButton;
    QLabel *BrushColorLabel;
    QFrame *brushColorFrame;
    QPushButton *brushcolorPushButton;
    QLabel *LineWidthLabel;
    QSpinBox * widthSpinBox;
    PaintArea *paintArea;




};

#endif // WIDGET_H
//paintarea.cpp
#include "paintarea.h"

#include <QPainter>
PaintArea::PaintArea(QWidget *parent) : QWidget(parent)
{

    QPalette pal=palette();
    pal.setColor(QPalette::Background,Qt::white);
    setAutoFillBackground(true);
    setPalette(pal);
    shape=Line;
}

void PaintArea::setShape(Shape s){
    shape=s;
    update();
}

void PaintArea::setBrush(QBrush b){
    brush=b;
    update();
}

void PaintArea::setPen(QPen p)
{
    pen = p;
    update();
}


void PaintArea::paintEvent(QPaintEvent *){
    QPainter p(this);
    p.setPen(pen);
    p.setBrush(brush);
    QRect rect(50,100,300,200);
    static const QPoint points[4]={
        QPoint(150,100),
        QPoint(300,150),
        QPoint(350,250),
        QPoint(100,300)
    };

    int startAngle=30*16;
    int spanAngle=120*16;

    QPainterPath path;
    path.addRect(150,150,100,100);
    path.moveTo(100,100);
    path.cubicTo(300,100,200,200,300,300);
    path.cubicTo(100,300,200,200,100,100);

    switch (shape) {
            case Line:
                p.drawLine(rect.topLeft(),rect.bottomRight());
                break;
            case Rectangle:
                p.drawRect(rect);
                break;
            case RoundRect:
                p.drawRoundRect(rect);
                break;
            case Ellipse:
                p.drawEllipse(rect);
                break;
            case Polygon:
                p.drawPolygon(points,4);
                break;
            case Polyline:
                p.drawPolyline(points,4);
                break;
            case Points:
                p.drawPoints(points,4);
                break;
            case Arc:
                p.drawArc(rect,startAngle,spanAngle);
                break;
            case Path:
                p.drawPath(path);
                break;
            case Text:
                p.drawText(rect,Qt::AlignCenter,tr("Hello Qt"));
                break;
            default:
                break;
        }
}



//widget.cpp
#include "widget.h"
#include <QLabel>
#include <QComboBox>
#include <QPainter>
#include "paintarea.h"
#include <QFrame>
#include <QPushButton>
#include <QSpinBox>
#include <QColorDialog>
#include <QPen>
#include <QColor>


Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //设置主窗口大小
       this->resize(700,400);

       QLabel * SharpLabel = new QLabel("形状:",this);
       shapeComboBox = new QComboBox(this);
       SharpLabel->setGeometry(430,20,60,40);
       shapeComboBox->setGeometry(500,20,150,40);
       shapeComboBox->addItem("Line",PaintArea::Line);
       shapeComboBox->addItem("Rectangle",PaintArea::Rectangle);
       shapeComboBox->addItem("RoundRect",PaintArea::RoundRect);
       shapeComboBox->addItem("Ellipse", PaintArea::Ellipse);
       shapeComboBox->addItem("Path", PaintArea::Path);
       shapeComboBox->addItem("Polyline", PaintArea::Polyline);
       shapeComboBox->addItem("Arc", PaintArea::Arc);
       shapeComboBox->addItem("Points", PaintArea::Points);
       shapeComboBox->addItem("Text", PaintArea::Text);

       QLabel * PenColorLabel = new QLabel("画笔颜色:",this);
       PenColorLabel->setGeometry(430,90,60,40);
       colorFrame = new QFrame(this);
       colorFrame->setGeometry(500,90,150,40);
       colorFrame->setAutoFillBackground(true);
       colorFrame->setPalette(QPalette(Qt::blue));
       QPushButton *colorPushButton = new QPushButton("修改",this);
       colorPushButton->setGeometry(650,90,50,40);

       QLabel * BrushColorLabel = new QLabel("画刷颜色:",this);
       BrushColorLabel->setGeometry(430,160,60,40);
       brushColorFrame = new QFrame(this);
       brushColorFrame->setGeometry(500,160,150,40);
       brushColorFrame->setAutoFillBackground(true);
       brushColorFrame->setPalette(QPalette(Qt::blue));
       QPushButton *brushcolorPushButton = new QPushButton("修改",this);
       brushcolorPushButton->setGeometry(650,160,50,40);

       QLabel * LineWidthLabel = new QLabel("线宽:",this);
       LineWidthLabel->setGeometry(430,250,60,40);
       widthSpinBox = new QSpinBox(this);
       widthSpinBox->setGeometry(500,250,60,40);
       widthSpinBox->setRange(0,20);


       connect(shapeComboBox,SIGNAL(activated(int)),this,SLOT(slotShape(int)));
       connect(colorPushButton,SIGNAL(clicked()),this,SLOT(slotPenColor()));
       connect(brushcolorPushButton,SIGNAL(clicked()),this,SLOT(slotBrushColor()));
       connect(widthSpinBox,SIGNAL(valueChanged(int)),this,SLOT(slotPenWidth(int)));

       paintArea = new PaintArea(this);
           //设置绘图区域窗口大小及位置
           paintArea->setGeometry(0,0,400,400);

}

Widget::~Widget()
{

}


void Widget::slotShape(int value){
    PaintArea::Shape shape
     = PaintArea::Shape(shapeComboBox->itemData(value,Qt::UserRole).toInt());
    paintArea->setShape(shape);

}

void Widget::slotPenColor()
{
    QColor color = QColorDialog::getColor(Qt::blue);
    colorFrame->setPalette(QPalette(color));
    int width = widthSpinBox->value();
    Qt::PenStyle style = Qt::SolidLine;
    Qt::PenCapStyle cap = Qt::RoundCap;
    Qt::PenJoinStyle join = Qt::RoundJoin;
    paintArea->setPen(QPen(color, width, style, cap, join));
}


void Widget::slotBrushColor()
{
    QColor color = QColorDialog::getColor(Qt::blue);
    brushColorFrame->setPalette(QPalette(color));
    paintArea->setBrush(QBrush(color));
}


void Widget::slotPenWidth(int value )
{
    QColor color = colorFrame->palette().color(QPalette::Window);
    Qt::PenStyle style = Qt::SolidLine;
    Qt::PenCapStyle cap = Qt::RoundCap;
    Qt::PenJoinStyle join = Qt::RoundJoin;
    paintArea->setPen(QPen(color, value, style, cap, join));
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值