1.界面展示
2.功能展示
新建画布:(背景的虚线格子花是录屏转gif的原因,原视频中没有花)
更新:之前一个画图按钮画下只能画每次只能画一个图形,后面实现了按钮按下一直画:
3.关于Graphics View绘图架构
由于QPainter画图形,不能实现对图形的选择、编辑、移动等操作,所以我的整个项目是基于Craphics View绘图架构来实现的
3.1 Craphics View
(1)Craphics View绘图架构介绍
Craphics View架构主要分为三个部分:视图、场景、图形项(图元)
- QGraphicsScene(场景):可以管理多个图形项
- QGraphicsItem(图形项):也就是图元,支持鼠标事件响应。
- QGraphicsView(视图):关联场景可以让场景中的所有图形项可视化
场景、视图、图元三者的关系图:
(2)QGrphicsView中一些常用操作接口
//添加场景
//设置关联显示的场景
void QGraphicsView::setScene(QGraphicsScene *scene)
// 设置场景在视图中可视部分的矩形区域
void QGraphicsView::setSceneRect(const QRectF &rect)
//场景外观设置操作
//设置场景在视图中的对齐方式,缺省是上下都居中
void QGraphicsView::setAlignment(Qt::Alignment alignment)
//设置场景场景的背景画刷
void QGraphicsView::setBackgroundBrush(const QBrush &brush)
//设置场景的前景画刷
void QGraphicsView::setForegroundBrush(const QBrush &brush)
//设置视图的绘图选项
void QGraphicsView::setRenderHints(QPainter::RenderHints hints)
//交互
//是否允许场景可交互,如果禁止交互,则任何键盘或鼠标操作都被忽略
void QGraphicsView::setInteractive(bool allowed)
//返回选择矩形框
QRect QGraphicsView::rubberBandRect() const
//选择模式 ,参数为枚举类型Qt : : ltemSelectionMode
Qt::ItemSelectionMode rubberBandSelectionMode() const
//获取视图坐标系中某个位置处的图形项
QGraphicsItem *QGraphicsView::itemAt(const QPoint &pos) const QGraphicsItem *QGraphicsView::itemAt(int x, int y) const
//获取场景中的所有、或者某个选择区域内图形项目的列表
QList<QGraphicsItem *> QGraphicsView::items() const QList<QGraphicsItem *> QGraphicsView::items(const QPoint &pos) const QList<QGraphicsItem *> QGraphicsView::items(int x, int y) const ....
//坐标
//将场景中的一个坐标转换为视图的坐标
QPolygon QGraphicsView::mapFromScene(const QRectF &rect) const
//将视图中的一个坐标转换为场景的坐标
QPointF QGraphicsView::mapToScene(const QPoint &point) const
(3)QGraphicsScene中一些常用操作接口
//场景
//设置场景的矩形区
void QGraphicsScene::setSceneRect(const QRectF &rect)
//分组
//创建图形项组
QGraphicsItemGroup *QGraphicsScene::createItemGroup(const QList<QGraphicsItem *> &items)
//解除一个图形项组
void QGraphicsScene::destroyItemGroup(QGraphicsItemGroup *group)
//输入焦点
//返回当前获得焦点的图形项
QGraphicsItem *QGraphicsScene::focusItem() const
//去除选择焦点
void QGraphicsScene::clearFocus()
//视图是否有焦点
bool QGraphicsScene::hasFocus() const
//图形项的操作
//添加一个已经创建的图形项
void QGraphicsScene::addItem(QGraphicsItem *item)
//删除图形项
void QGraphicsScene::removeItem(QGraphicsItem *item)
//清除所有图形项
[slot] void QGraphicsScene::clear()
//返回鼠标抓取的图形项
QGraphicsItem *QGraphicsScene::mouseGrabberItem() const
//返回选择的图形项列表
QList<QGraphicsItem *> QGraphicsScene::selectedItems() const
//清除所有选择
[slot] void QGraphicsScene::clearSelection()
//获取某个位置处的顶层图形项
QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform &deviceTransform) const QGraphicsItem *QGraphicsScene::itemAt(qreal x, qreal y, const QTransform &deviceTransform) const
//返回某个矩形区域、多边形等选择区域内的图形项列表
QList<QGraphicsItem *> QGraphicsScene::items(Qt::SortOrder order = Qt::DescendingOrder) const
//添加图形项
//添加一个椭圆 QGraphicsEllipseItem *QGraphicsScene::addEllipse(const QRectF &rect, const QPen &pen = QPen(), const QBrush &brush = QBrush()); //添加一条直线 QGraphicsLineItem *QGraphicsScene::addLine(qreal x1, qreal y1, qreal x2, qreal y2, const QPen &pen = QPen()); //添加一个绘图路径 QGraphicsPathItem *QGraphicsScene::addPath(const QPainterPath &path, const QPen &pen = QPen(), const QBrush &brush = QBrush()); //添加一个图片 QGraphicsPixmapItem *QGraphicsScene::addPixmap(const QPixmap &pixmap); //添加一个多边形 QGraphicsPolygonItem *QGraphicsScene::addPolygon(const QPolygonF &polygon, const QPen &pen = QPen(), const QBrush &brush = QBrush()); //添加一个矩形 QGraphicsRectItem *QGraphicsScene::addRect(const QRectF &rect, const QPen &pen = QPen(), const QBrush &brush = QBrush()); //添加简单文字 QGraphicsSimpleTextItem *QGraphicsScene::addSimpleText(const QString &text, const QFont &font = QFont()); //添加字符串 QGraphicsTextItem *QGraphicsScene::addText(const QString &text, const QFont &font = QFont()); //添加界面组件 QGraphicsProxyWidget *QGraphicsScene::addWidget(QWidget *widget, Qt::WindowFlags wFlags = Qt::WindowFlags());
(4)QGraphicsItem中一些常用操作接口
//属性设置
//设置图形项的操作属性,例如,可选择,可移动等
void QGraphicsItem::setFlags(QGraphicsItem::GraphicsItemFlags flags)
//设置透明度
void QGraphicsItem::setOpacity(qreal opacity)
//设置图形效果
void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
//图形项是否被选中
void QGraphicsItem::setSelected(bool selected)
//用户自定义数据
void QGraphicsItem::setData(int key, const QVariant &value)
//坐标
//图形项的X坐标
void QGraphicsItem::setX(qreal x)
//图形项的Y坐标
void QGraphicsItem::setY(qreal y)
//图形项的Z值,Z值控制图形项的叠放次序
void QGraphicsItem::setZValue(qreal z)
//图形项在父项中的位置
void QGraphicsItem::setPos(const QPointF &pos)
//返回图形项在场景中的坐标,相当于调用mapToScene(0,0)
QPointF QGraphicsItem::scenePos() const
//坐标变换
//复位坐标系,取消所有坐标变换
void QGraphicsItem::resetTransform()
//旋转一定角度,参数为正数时表示顺时针旋转
void QGraphicsItem::setRotation(qreal angle)
//按比例缩放,缺省值为1
void QGraphicsItem::setScale(qreal factor)
//坐标映射
//将另一个图形项的一个点映射到本图形项到坐标系
QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPointF &point) const
//将父项的一个点映射到本图形项的坐标系
QPointF QGraphicsItem::mapFromParent(const QPointF &point) const
//将场景中的一个点映射到本图项到坐标系
QPointF QGraphicsItem::mapFromScene(const QPointF &point) const
//将本图形项内到一个点映射到另一个图形项的坐标系
QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterPath &path) const QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y) const QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPointF &point) const QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QRectF &rect) const QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPolygonF &polygon) const ...
//将本图形项内的一个点映射到父项坐标系
QPointF QGraphicsItem::mapToParent(const QPointF &point) const QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const QPointF QGraphicsItem::mapToParent(qreal x, qreal y) const
//将本图形项内到一个点映射到场景坐标系
QPointF QGraphicsItem::mapToScene(const QPointF &point) const QPolygonF QGraphicsItem::mapToScene(const QRectF &rect) const QPolygonF QGraphicsItem::mapToScene(const QPolygonF &polygon) const QPainterPath QGraphicsItem::mapToScene(const QPainterPath &path) const QPointF QGraphicsItem::mapToScene(qreal x, qreal y) const QPolygonF QGraphicsItem::mapToScene(qreal x, qreal y, qreal w, qreal h) const
4.项目整体结构
4.1 项目中使用的类
项目总结:
项目上遇到的一些问题:
1.开始在tabWidget上添加画布时,不能做画,选择要画的图形后,一点击画笔程序就崩溃退出,然后我添加了一些判定条件,如果tabWidget->currentIndex() < 0时,指针赋值失败,后来加了判断条件后,就可以了,再后来我直接改进,打开应用程序窗口时,就在会在tabWidget上创建画布。
2.在mainwindow.cpp中我重写了mouseDoubleClickEvent方法,双击图形时,更新右边的属性列表,但是在双击空白的视图view时程序就会闪退,后来使用的解决方法就是加了判定条件,如果已经选择了图形,双击图形就更新属性列表,如果没有选择图形,只单纯的双击画布,就忽视事件。具体代码实现如下:
//双击图形更新图形的属性列表
void MainWindow::mouseDoubleClickEvent(QMouseEvent *event)
{ QGraphicsScene * scene = m_scene;
if (scene && !scene->selectedItems().isEmpty()) {
if (scene->selectedItems().first()->isSelected()) {
updateItemProperty(); //更新属性列表
}
}else{
event->ignore();
}
}
3.在按下如下按钮时,如果图形没有被选中,程序会崩溃闪退,后来我加了一些判定条件,比如在选中的图形大于1时才能进行组合、对齐和拉伸等操作 ,该问题也完美解决
void MainWindow::aglin() {
graphicsScene * scene = dynamic_cast<graphicsScene*>(m_scene);
int selectedItemCount = scene->selectedItems().count();
if(ui->tabWidget->currentIndex() >= 0 && scene && selectedItemCount > 1){
if (sender() == ui->top_align_button){
scene->align(TOP_ALIGN);
}else if(sender() == ui->bottom_align_button){
scene->align(BOTTOM_ALIGN);
}else if(sender() == ui->left_align_button){
scene->align(LEFT_ALIGN);
}else if(sender() == ui->right_align_button){
scene->align(RIGHT_ALIGN);
}else if(sender() == ui->horizontal_align){
scene->align(HORZEVEN_ALIGN);
}else if(sender() == ui->vertical_align){
scene->align(VERTEVEN_ALIGN);
}else if(sender() == ui->vertical_space_Button){
scene->align(HORZEVEN_SPACE);
}else if(sender() == ui->horizontal_space_Button){
scene->align(VERTEVEN_SPACE);
}else if(sender() == ui->widthButton){
scene->align(WIDTH_ALIGN);
}else if(sender() == ui->heightButton){
scene->align(HEIGHT_ALIGN);
}
}
}
以上就是我在开发时遇到的一些问题,当然还有一些小问题,就不一一阐述了。