演示效果

工具栏通常位于菜单栏的下方,上面存放着一些小按钮,如下图所示。

以下所有功能都是直接通过代码实现,而不是在设计模式下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实现简易画板代码解析【工具栏】【画板】相关推荐

  1. Qt Creator粘贴和获取代码段

    Qt Creator粘贴和获取代码段 粘贴和获取代码段 指定代码粘贴的设置 使用代码粘贴服务 粘贴和获取代码段 在Qt Creator中,您可以将代码段粘贴到服务器或从服务器中获取代码段.要粘贴和获取 ...

  2. Qt Creator缩进文字或代码

    Qt Creator缩进文字或代码 缩进文字或代码 缩进C ++文件 自动格式化和缩进 缩进QML文件 缩进Nim文件 缩进其他文本文件 指定选项卡设置 指定制表符和缩进 指定键入选项 指定内容设置 ...

  3. qt creator 信号与槽 代码实现 (二)

    一.通过 go to  slot 选项实现 1.单击 "今天",选择  go to slots 2.在 mianwindow.h 文件下产生了 private slots: voi ...

  4. Qt Creator 代码自动补全设置

    Qt Creator具有自己的代码补全快捷键[Ctrl]+[Space] 但是在使用过程中,效果不明显,或者没有效果.可能是与输入法的切换冲突了.因此可以通过设置,避免这个问题. 解决方法: 1.打开 ...

  5. Qt Creator检查代码语法

    Qt Creator检查代码语法 检查代码语法 查看注释 指定线注释位置 JavaScript和QML错误代码 重置代码模型 检查QML和JavaScript 自动格式化QML / JS文件 检查代码 ...

  6. Qt Creator在外部应用程序上运行Valgrind工具

    Qt Creator在外部应用程序上运行Valgrind工具 在外部应用程序上运行Valgrind工具 在外部应用程序上运行Valgrind工具 Qt Creator集成了Valgrind代码分析工具 ...

  7. Qt Creator测验Testing

    Qt Creator测验 测验 调试 分析代码 运行自动测试 测验 调试 如果您将Qt Creator作为Qt的一部分安装,则GNU Symbolic Debugger会自动安装,并且在创建新项目后应 ...

  8. Qt Creator编码

    Qt Creator编码 编码 编写代码 寻找 重构 美化源代码 配置编辑器 相关话题 编辑MIME类型 造型 编辑状态图 编码 编写代码 编写,编辑和导航源代码是应用程序开发中的核心任务.因此,代码 ...

  9. Qt Creator使用Clang代码模型解析C ++文件

    Qt Creator使用Clang代码模型解析C ++文件 使用Clang代码模型解析C ++文件 关于Clang代码模型 配置C语代码模型 lang检查 在项目级别指定Clang代码模型设置 使用编 ...

最新文章

  1. CF533A Berland Miners
  2. 爱奇艺一程序员用 10 万元“买”了个北京户口
  3. 【 MATLAB 】协方差 cov以及协方差矩阵基础知识
  4. YEP共享平台释放宜人贷无限潜力
  5. c++ windows编译器 amd平台_不同操作系统下的C/C++ 编译器,C/C++新手须知,零基础学习C语言...
  6. 数据库实验7 数据库视图的定义与使用
  7. Java重写《C经典100题》 --08
  8. Java基础:MySQL
  9. 2015计算机软考试题及答案,2015年计算机软考网络工程师练习试题及答案
  10. Office 与 Visio安装冲突
  11. java盖章后原来印章模糊了_公章部分字迹盖不清楚怎么处理
  12. java学习感想_Java学习感想
  13. View事件分发机制分析
  14. 浙大版《C语言程序设计(第3版)》题目集(编程题q41-q50)
  15. 通过字体映射 Fontlink 美化中文显示
  16. C中二级指针与它指向的一级指针之间的秘密(深入++*pptr)
  17. 关于IOS调用微信支付jsapi不起作用的解决方法
  18. Abaqus常用小技巧
  19. 汽车零部件行业应用APS的必要性
  20. location.href 与 location.search

热门文章

  1. echarts 弹出放大_Echarts:初始放大地图类型
  2. 贝塞尔曲线实现抛物线运动,投掷功能实现
  3. 输入输出系统--习题
  4. OPENCV图片数字识别
  5. 钙锌复合稳定剂-市场现状及未来发展趋势
  6. java desktop_Java Desktop开发资源
  7. nvh个人检测下载_变速箱NVH质量检验系统.pdf
  8. radmin不能发送Ctrl+Alt+Del的解决办法
  9. 东北大学 Java练习 作业2 Implementing the Collections in the Gourmet Coffee System
  10. 提高我们微博互粉的效率,使用一键关注Chrome扩展程序