一些问题:
- 在Qt编译好之后运行程序时提示:程序异常结束。The process was ended forcefully. …exe crashed.:通常情况是空指针或者数组越界问题,少数情况也有自己少写或者多写了一些无效或重复的代码而引起。
一些知识点:
- 建一个主窗口,在其中加入所需控件及设置绘图区域:
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);
- 绘图区域另设类与函数
- 在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():随即触发重绘,根据新数据重绘,若没有则新的图样不会显示。
- 绘图区域背景设置与函数实现:
//设置背景白色
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));
}