Qt Creator实现简易画板代码解析【工具栏】【画板】
演示效果
工具栏通常位于菜单栏的下方,上面存放着一些小按钮,如下图所示。
以下所有功能都是直接通过代码实现,而不是在设计模式下ui界面通过拖拽实现。当然,它是可以用拖拽实现的。
引入图片资源
图片资源主要是用于动作的图标。在工程文件里面创建一个picture文件夹,然后在PPT截图了两张图片用作图标,图片格式没要求。
在该项目的基础上,点击QT菜单栏【文件】→【新建文件或项目】,左边选择【Qt】,中间选择【Qt Resource File】,选择【Chose】,自己命个名,然后不断下一步即可。
会发现工程里面多了Resources文件夹,这个myres就是我刚才命名的。
右键点击Resources,选择【Add Existing Directory】(添加现存的目录),出现以下界面把图片选上就行了。
然后目录就变成了这样,至此已经完成图片资源的导入。
新建工具栏并导入动作
mainwindow.cpp文件内容;
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QToolBar *bar = new QToolBar; //新建工具栏this->addToolBar(bar); //将工具栏添加到这个窗口QActionGroup *group = new QActionGroup(bar); //新建动作组合QAction *drawLineAction = new QAction("Line", bar);drawLineAction->setIcon(QIcon(":/picture/line.jpg")); //图标drawLineAction->setToolTip(tr("Draw a line1.")); //工具栏提示drawLineAction->setStatusTip(tr("Draw a line."));//下面状态栏文本drawLineAction->setCheckable(true);drawLineAction->setChecked(true);group->addAction(drawLineAction); //向动作组合添加一个新动作bar->addAction(drawLineAction); //向工具栏添加动作QAction *drawRectAction = new QAction("Rectangle", bar);drawRectAction->setIcon(QIcon(":/picture/rect.jpg"));drawRectAction->setToolTip(tr("Draw a rectangle1."));drawRectAction->setStatusTip(tr("Draw a rectangle."));drawRectAction->setCheckable(true);group->addAction(drawRectAction);bar->addAction(drawRectAction);}MainWindow::~MainWindow()
{delete ui;
}
mainwindow.h文件内容,主要是要引入对应的include。
效果:
代码解析
QToolBar *bar = new QToolBar; //新建工具栏this->addToolBar(bar); //将工具栏添加到这个窗口
工具栏对应的类是QToolBar,使用需要添加#include <QToolBar>
。接下来要用addToolBar函数把工具栏添加到主窗口,也就是this对应的指针。addToolBar函数通过名字就很好理解,就是往某个窗口添加工具栏。
QActionGroup *group = new QActionGroup(bar); //新建动作组合
QActionGroup类对应的是动作组合,使用需要添加#include <QActionGroup>
。这个类对应的是多个动作,适应的情况是存在多个动作,但是某一时刻只有一个动作是激活状态,即他们是互斥的。比如常见的左对齐、右对齐、居中对齐,他们是仅有一个生效的。利用QActionGroup类可以简单达到这种互斥的效果。
QAction *drawLineAction = new QAction("Line", bar);drawLineAction->setIcon(QIcon(":/picture/line.jpg")); //图标drawLineAction->setToolTip(tr("Draw a line1.")); //工具栏提示drawLineAction->setStatusTip(tr("Draw a line."));//下面状态栏文本drawLineAction->setCheckable(true);drawLineAction->setChecked(true);group->addAction(drawLineAction); //向动作组合添加一个新动作bar->addAction(drawLineAction); //向工具栏添加动作
QAction类对应的是单个动作,使用需要添加#include <QAction>
。第一句代码就是生成了一个动作实例,父对象是bar,即工具栏。下面对应的是这个动作的不同属性,通过对应的函数分别设置。
1.setIcon函数:图标很好理解,使用图标需要提前导入图片资源,也就是文章最前面部分。并且要用QIcon强制转换为图标类型。
2.setToolTip函数:当鼠标放在图标上面出现的文字提示。
3.SetStatusTip函数:当鼠标放在图标上,状态栏出现的文字提示。
3.setCheckable函数:
这个函数设定这个动作是否是可复用动作。默认情况它的取值是false,即不复用。对应的表现就是按下动作之后,会自动弹起。类比一下按钮,按一下按钮,按钮会自动恢复。类似保存文件之类动作,按下就执行动作,然后自动弹起,并不存在两种状态,所以保持默认false即可。
如果通过函数设定为true,那就是可复用状态。那这个属性适用于哪种场景呢?比如字体的粗细,按下就是粗体,然后保持粗体,再按下弹起来,恢复正常。这就是动作的复用,存在两种状态。
4.setChecked函数:
这个函数对应的是上面那个属性,只有动作是checkable状态,才可以设置。默认情况下,checked属性是false,即不选中。如果设置为true,当你打开的时候,这个动作就默认已经被选中。
在状态栏添加标签控件
QLabel是标签控件,使用需要#include <QLabel>
。主要用于显示信息。statusBar是新建的MainWindow项目默认的状态栏,然后通过addWidget函数把标签控件加入状态栏,后续可以直接在标签里面设置显示文本,这样状态栏就会出现对应信息。
实现槽与信号的连接
1.新建信号与槽函数
上述我们只是实现了工具栏的框架,只能点一点,看一看,但是没啥反应。
在mainwindow.h中添加自定义的信号和两个槽函数,这个自定义的信号用于发送画线还是画矩形,函数有一个参数来表示shape。Shape类也是自定义的类,后面会继续介绍。
signals:void changeCurrentShape(Shape::Code newShape);private slots:void drawLineActionTriggered();void drawRectActionTriggered();
在mainwindow.cpp文件实现两个槽函数,即发送对应的信号。至于这两个槽函数由什么控件触发,后续介绍。
void MainWindow::drawLineActionTriggered()
{ emit changeCurrentShape(Shape::Line);
} void MainWindow::drawRectActionTriggered()
{ emit changeCurrentShape(Shape::Rect);
}
2.connect连接
在mainwindow.cpp文件中的MainWindow::MainWindow函数添加三个connect将信号与槽对接起来。
drawLineAction和drawRectAction是上面创建的两个动作,点击这两个动作会发出triggered信号。但是这个信号是不带参数的,而接收信号的画板就区分不了两者。所以才需要新建一个新的带参数的信号。
流程如下:点击画直线图标,触发triggerrd信号,进入槽函数drawLineActionTriggered函数,在此函数emit一个带有Shape::Line参数的信号。这样画板就知道该画直线了。
//连接信号与槽connect(drawLineAction, SIGNAL(triggered()), this, SLOT(drawLineActionTriggered())); connect(drawRectAction, SIGNAL(triggered()), this, SLOT(drawRectActionTriggered())); connect(this, SIGNAL(changeCurrentShape(Shape::Code)), paintWidget, SLOT(setCurrentShape(Shape::Code)));
3.建立画图板
新建下面这些新文件。
1)shape类
先看看shape相关文件,这是Line和Rect的父类。
shape.h
#ifndef SHAPE_H
#define SHAPE_H#include <QtGui>
class Shape
{
public:enum Code {Line,Rect};Shape();void setStart(QPoint s){start = s;}void setEnd(QPoint e){end = e;}QPoint startPoint(){return start;}QPoint endPoint(){return end;}void virtual paint(QPainter & painter) = 0;protected:QPoint start;QPoint end;
};
#endif // SHAPE_H
Shape存在两个QPoint点,起点和终点,通过这两个数据确定直线和矩形的大小。paint函数是一个虚函数,实际实现需要子类具体实现。Code是一个枚举向量,用来表示直线还是矩形。
shape.cpp
#include "shape.h"Shape::Shape()
{
}
2)line类
line.h
#ifndef LINE_H
#define LINE_H
#include "shape.h"class Line : public Shape
{
public:Line();void paint(QPainter &painter);
};
#endif // LINE_H
line.cpp
#include "line.h"Line::Line()
{
}void Line::paint(QPainter &painter)
{painter.drawLine(start, end);
}
line类继承于Shape,主要就是实现了画直线的操作。QPainter类是专门用于画图的类,使用需要#include <QPainter>
。drawLine是内置的画直线函数,只需要起点和终点两个参数,这两参数来自于父类Shape。
3)Rect类
rect.h
#ifndef RECT_H
#define RECT_H
#include "shape.h"class Rect : public Shape
{
public:Rect();void paint(QPainter &painter);
};
#endif // RECT_H
rect.cpp
#include "rect.h"Rect::Rect()
{
}void Rect::paint(QPainter &painter)
{painter.drawRect(start.x(), start.y(),end.x() - start.x(), end.y() - start.y());
}
和Line类的区别就是换了drawRect函数,这是画矩形的专门函数。四个参数分别代表左上角顶点的x、y、矩形的宽度、矩形的高度。start和end是QPoint类,他们的成员函数x()和y()可以获取这个点的xy坐标。
4)paintwidget类
PaintWidget是自定义的画板类,需要添加对应的头文件以及源文件。
paintwidget.h文件。
#ifndef PAINTWIDGET_H
#define PAINTWIDGET_H
#include <QtGui>
#include <QDebug>
#include "shape.h"
#include "line.h"
#include "rect.h"
#include <QWidget>class PaintWidget : public QWidget
{Q_OBJECTpublic:PaintWidget(QWidget *parent = 0);public slots:void setCurrentShape(Shape::Code s){if(s != currShapeCode) {currShapeCode = s;}}protected:void paintEvent(QPaintEvent *event);void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);private:Shape::Code currShapeCode;Shape *shape;bool perm;QList<Shape*> shapeList;
};
#endif // PAINTWIDGET_H
PaintWidget类定义了一个槽函数,用于接收绘制形状的Shape::Code.
PaintWidget重定义了三个关于鼠标的事件:mousePressEvent,mouseMoveEvent和mouseReleaseEvent。这三个函数是父类的虚函数,我们可以重新定义函数内容。
QList是一个列表,主要是用于存储历史图片。
paintwidget.cpp文件。
#include "paintwidget.h"PaintWidget::PaintWidget(QWidget *parent): QWidget(parent), currShapeCode(Shape::Line), shape(NULL), perm(false)
{setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}void PaintWidget::paintEvent(QPaintEvent *event)
{QPainter painter(this);painter.setBrush(Qt::white);painter.drawRect(0, 0, size().width(), size().height());foreach(Shape * shape, shapeList) {shape->paint(painter);}
}void PaintWidget::mousePressEvent(QMouseEvent *event)
{switch(currShapeCode){case Shape::Line:{shape = new Line;break;}case Shape::Rect:{shape = new Rect;break;}}if(shape != NULL) {perm = false;shapeList<<shape;shape->setStart(event->pos());shape->setEnd(event->pos());}
}void PaintWidget::mouseMoveEvent(QMouseEvent *event)
{if(shape && !perm) {shape->setEnd(event->pos());update();}
}void PaintWidget::mouseReleaseEvent(QMouseEvent *event)
{perm = true;
}
鼠标点击函数: 根据PaintWidget类的currShapeCode决定绘制直线还是矩形。shape是PaintWidget类一个指向Shape的指针。perm是PaintWidget类的成员,表示绘制是否结束。
将目前的图形shape存入列表shaoeList。将目前鼠标的位置pos设定为图形的起点和终点。
鼠标移动函数:
只要perm标志位没有变为true,在移动的过程中,将鼠标的位置设定为shape的结束点,并且通过update更新画板。
update函数是paintEvent提供的刷新函数,每次调用,都会重绘事件。相当于画笔随着鼠标的移动在不断地画线。
鼠标释放函数:
当鼠标释放的时候,perm变为true,所以此时移动鼠标,就不会改变终点,也不会刷新画板,相当于就图片就确定了。
重绘事件处理函数:
基础控件类QWidget提供的paintEvent函数是一个纯虚函数,继承它的子类想要进行重绘就必须重新实现。通过QPainter类定义了一个画家,通过setBrush函数设置画刷颜色为白色(主要是内部填充)。
drawRect函数就是画了一个和窗口等大的白底框,如果没有这句代码,背景就是灰色的。
foreach就是把shapeList的图形都画出来。比如我们先画了一个矩形,再画直线,直线update的时候就会把矩形给覆盖掉。所以每次刷新都需要把之前的图案再次画出来。
在mainwindow.cpp文件中的MainWindow::MainWindow函数添加画板。
//定义一块画图板PaintWidget *paintWidget = new PaintWidget(this);//设置为中心窗口setCentralWidget(paintWidget);
参考文章:
Qt 一个简易画板的实现(QWidget)
Qt Creator实现简易画板代码解析【工具栏】【画板】相关推荐
- Qt Creator粘贴和获取代码段
Qt Creator粘贴和获取代码段 粘贴和获取代码段 指定代码粘贴的设置 使用代码粘贴服务 粘贴和获取代码段 在Qt Creator中,您可以将代码段粘贴到服务器或从服务器中获取代码段.要粘贴和获取 ...
- Qt Creator缩进文字或代码
Qt Creator缩进文字或代码 缩进文字或代码 缩进C ++文件 自动格式化和缩进 缩进QML文件 缩进Nim文件 缩进其他文本文件 指定选项卡设置 指定制表符和缩进 指定键入选项 指定内容设置 ...
- qt creator 信号与槽 代码实现 (二)
一.通过 go to slot 选项实现 1.单击 "今天",选择 go to slots 2.在 mianwindow.h 文件下产生了 private slots: voi ...
- Qt Creator 代码自动补全设置
Qt Creator具有自己的代码补全快捷键[Ctrl]+[Space] 但是在使用过程中,效果不明显,或者没有效果.可能是与输入法的切换冲突了.因此可以通过设置,避免这个问题. 解决方法: 1.打开 ...
- Qt Creator检查代码语法
Qt Creator检查代码语法 检查代码语法 查看注释 指定线注释位置 JavaScript和QML错误代码 重置代码模型 检查QML和JavaScript 自动格式化QML / JS文件 检查代码 ...
- Qt Creator在外部应用程序上运行Valgrind工具
Qt Creator在外部应用程序上运行Valgrind工具 在外部应用程序上运行Valgrind工具 在外部应用程序上运行Valgrind工具 Qt Creator集成了Valgrind代码分析工具 ...
- Qt Creator测验Testing
Qt Creator测验 测验 调试 分析代码 运行自动测试 测验 调试 如果您将Qt Creator作为Qt的一部分安装,则GNU Symbolic Debugger会自动安装,并且在创建新项目后应 ...
- Qt Creator编码
Qt Creator编码 编码 编写代码 寻找 重构 美化源代码 配置编辑器 相关话题 编辑MIME类型 造型 编辑状态图 编码 编写代码 编写,编辑和导航源代码是应用程序开发中的核心任务.因此,代码 ...
- Qt Creator使用Clang代码模型解析C ++文件
Qt Creator使用Clang代码模型解析C ++文件 使用Clang代码模型解析C ++文件 关于Clang代码模型 配置C语代码模型 lang检查 在项目级别指定Clang代码模型设置 使用编 ...
最新文章
- CF533A Berland Miners
- 爱奇艺一程序员用 10 万元“买”了个北京户口
- 【 MATLAB 】协方差 cov以及协方差矩阵基础知识
- YEP共享平台释放宜人贷无限潜力
- c++ windows编译器 amd平台_不同操作系统下的C/C++ 编译器,C/C++新手须知,零基础学习C语言...
- 数据库实验7 数据库视图的定义与使用
- Java重写《C经典100题》 --08
- Java基础:MySQL
- 2015计算机软考试题及答案,2015年计算机软考网络工程师练习试题及答案
- Office 与 Visio安装冲突
- java盖章后原来印章模糊了_公章部分字迹盖不清楚怎么处理
- java学习感想_Java学习感想
- View事件分发机制分析
- 浙大版《C语言程序设计(第3版)》题目集(编程题q41-q50)
- 通过字体映射 Fontlink 美化中文显示
- C中二级指针与它指向的一级指针之间的秘密(深入++*pptr)
- 关于IOS调用微信支付jsapi不起作用的解决方法
- Abaqus常用小技巧
- 汽车零部件行业应用APS的必要性
- location.href 与 location.search
热门文章
- echarts 弹出放大_Echarts:初始放大地图类型
- 贝塞尔曲线实现抛物线运动,投掷功能实现
- 输入输出系统--习题
- OPENCV图片数字识别
- 钙锌复合稳定剂-市场现状及未来发展趋势
- java desktop_Java Desktop开发资源
- nvh个人检测下载_变速箱NVH质量检验系统.pdf
- radmin不能发送Ctrl+Alt+Del的解决办法
- 东北大学 Java练习 作业2 Implementing the Collections in the Gourmet Coffee System
- 提高我们微博互粉的效率,使用一键关注Chrome扩展程序