1. Interface display
2. Function display
Create a new canvas: (The dotted plaid flowers in the background are the reason why the screen recording is converted to gif. There are no flowers in the original video)
Update: Previously, a drawing button could only draw one shape at a time. Later, it was implemented to draw continuously when the button is pressed:
3. About Graphics View drawing architecture
Since QPainter draws graphics, it cannot implement operations such as selecting, editing, and moving graphics, so my entire project is based on the Graphics View drawing architecture.
3.1 Graphics View
(1) Introduction to Graphics View drawing architecture
The Graphics View architecture is mainly divided into three parts: views, scenes, and graphics items (primitives)
- QGraphicsScene (scene): can manage multiple graphics items
- QGraphicsItem (graphic item): It is also a graphic element and supports mouse event response.
- QGraphicsView (view): Associated scenes can visualize all graphic items in the scene
The relationship diagram between scenes, views, and primitives:
(2) Some common operation interfaces in QGrphicsView
//Add scene
//Set the associated display scene
void QGraphicsView::setScene(QGraphicsScene *scene)// Set the rectangular area of the visible part of the scene in the view
void QGraphicsView::setSceneRect(const QRectF & amp;rect)
//Scene appearance setting operation
//Set the alignment of the scene in the view. The default is to center both top and bottom.
void QGraphicsView::setAlignment(Qt::Alignment alignment)//Set the background brush of the scene scene
void QGraphicsView::setBackgroundBrush(const QBrush & amp;brush)//Set the foreground brush of the scene
void QGraphicsView::setForegroundBrush(const QBrush & amp;brush)//Set the drawing options of the view
void QGraphicsView::setRenderHints(QPainter::RenderHints hints)
//Interaction
//Whether the scene is allowed to be interactive, if interaction is prohibited, any keyboard or mouse operations are ignored
void QGraphicsView::setInteractive(bool allowed)//Return to the selection rectangle
QRect QGraphicsView::rubberBandRect() const//Selection mode, the parameter is the enumeration type Qt::ltemSelectionMode
Qt::ItemSelectionMode rubberBandSelectionMode() const//Get the graphic item at a certain position in the view coordinate system
QGraphicsItem *QGraphicsView::itemAt(const QPoint & amp;pos) const QGraphicsItem *QGraphicsView::itemAt(int x, int y) const//Get a list of all graphic items in the scene or a certain selection area
QList<QGraphicsItem *> QGraphicsView::items() const QList<QGraphicsItem *> QGraphicsView::items(const QPoint & amp;pos) const QList<QGraphicsItem *> QGraphicsView::items(int x, int y) const ....
//coordinate
//Convert a coordinate in the scene to the coordinates of the view
QPolygon QGraphicsView::mapFromScene(const QRectF & amp;rect) const//Convert a coordinate in the view to the coordinates of the scene
QPointF QGraphicsView::mapToScene(const QPoint & amp;point) const
(3) Some common operation interfaces in QGraphicsScene
//Scenes
//Set the rectangular area of the scene
?void QGraphicsScene::setSceneRect(const QRectF & amp;rect)
//Group
//Create graphic item group
QGraphicsItemGroup *QGraphicsScene::createItemGroup(const QList<QGraphicsItem *> & amp;items)//Remove a graphics item group
void QGraphicsScene::destroyItemGroup(QGraphicsItemGroup *group)
//Input focus
//Return the currently focused graphic item
QGraphicsItem *QGraphicsScene::focusItem() const//Remove selection focus
void QGraphicsScene::clearFocus()//Whether the view has focus
bool QGraphicsScene::hasFocus() const
//Operation of graphic items
//Add an already created graphic item
void QGraphicsScene::addItem(QGraphicsItem *item)//Delete graphic item
void QGraphicsScene::removeItem(QGraphicsItem *item)//Clear all graphic items
[slot] void QGraphicsScene::clear()//Return the graphic item captured by the mouse
QGraphicsItem *QGraphicsScene::mouseGrabberItem() const//Return the selected graphic item list
QList<QGraphicsItem *> QGraphicsScene::selectedItems() const//Clear all selections
[slot] void QGraphicsScene::clearSelection()//Get the top-level graphic item at a certain position
QGraphicsItem *QGraphicsScene::itemAt(const QPointF & amp;position, const QTransform & amp;deviceTransform) const QGraphicsItem *QGraphicsScene::itemAt(qreal x, qreal y, const QTransform & amp;deviceTransform) const//Return a list of graphic items within a certain rectangular area, polygon, etc. selection area
QList<QGraphicsItem *> QGraphicsScene::items(Qt::SortOrder order = Qt::DescendingOrder) const
//Add graphic item
//Add an ellipse QGraphicsEllipseItem *QGraphicsScene::addEllipse(const QRectF & amp;rect, const QPen & amp;pen = QPen(), const QBrush & amp;brush = QBrush()); //Add a straight line QGraphicsLineItem *QGraphicsScene::addLine(qreal x1, qreal y1, qreal x2, qreal y2, const QPen & amp;pen = QPen()); //Add a drawing path QGraphicsPathItem *QGraphicsScene::addPath(const QPainterPath & amp;path, const QPen & amp;pen = QPen(), const QBrush & amp;brush = QBrush()); //Add a picture QGraphicsPixmapItem *QGraphicsScene::addPixmap(const QPixmap & amp;pixmap); //Add a polygon QGraphicsPolygonItem *QGraphicsScene::addPolygon(const QPolygonF & amp;polygon, const QPen & amp;pen = QPen(), const QBrush & amp;brush = QBrush()); //Add a rectangle QGraphicsRectItem *QGraphicsScene::addRect(const QRectF & amp;rect, const QPen & amp;pen = QPen(), const QBrush & amp;brush = QBrush()); //Add simple text QGraphicsSimpleTextItem *QGraphicsScene::addSimpleText(const QString & amp;text, const QFont & amp;font = QFont()); //Add string QGraphicsTextItem *QGraphicsScene::addText(const QString & amp;text, const QFont & amp;font = QFont()); //Add interface components QGraphicsProxyWidget *QGraphicsScene::addWidget(QWidget *widget, Qt::WindowFlags wFlags = Qt::WindowFlags());
(4) Some common operation interfaces in QGraphicsItem
//Property settings
//Set the operation attributes of the graphic item, for example, selectable, movable, etc.
void QGraphicsItem::setFlags(QGraphicsItem::GraphicsItemFlags flags)//Set transparency
void QGraphicsItem::setOpacity(qreal opacity)//Set graphic effects
void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)//Whether the graphic item is selected
void QGraphicsItem::setSelected(bool selected)//User-defined data
void QGraphicsItem::setData(int key, const QVariant & amp;value)
//coordinate
//X coordinate of graphic item
void QGraphicsItem::setX(qreal x)//Y coordinate of graphic item
void QGraphicsItem::setY(qreal y)//Z value of graphic items, Z value controls the stacking order of graphic items
void QGraphicsItem::setZValue(qreal z)//The position of the graphic item in the parent item
void QGraphicsItem::setPos(const QPointF & amp;pos)//Return the coordinates of the graphic item in the scene, equivalent to calling mapToScene(0,0)
QPointF QGraphicsItem::scenePos() const
//Coordinate transformation
//Reset the coordinate system and cancel all coordinate transformations
void QGraphicsItem::resetTransform()//Rotate a certain angle. When the parameter is a positive number, it means clockwise rotation.
void QGraphicsItem::setRotation(qreal angle)//Scale proportionally, the default value is 1
void QGraphicsItem::setScale(qreal factor)
//Coordinate mapping
//Map a point of another graphic item to this graphic item to the coordinate system
QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPointF & amp;point) const//Map a point of the parent item to the coordinate system of this graphic item
QPointF QGraphicsItem::mapFromParent(const QPointF & amp;point) const//Map a point in the scene to this graph item to the coordinate system
QPointF QGraphicsItem::mapFromScene(const QPointF & amp;point) const//Map a point within this graphic item to the coordinate system of another graphic item
QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterPath & amp;path) const QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y) const QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPointF & amp;point) const QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QRectF & amp;rect) const QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPolygonF & amp;polygon) const ...//Map a point within this graphic item to the parent coordinate system
QPointF QGraphicsItem::mapToParent(const QPointF & amp;point) const QPolygonF QGraphicsItem::mapToParent(const QRectF & amp;rect) const QPolygonF QGraphicsItem::mapToParent(const QPolygonF & amp;polygon) const QPolygonF QGraphicsItem::mapToParent(const QPolygonF & amp;polygon) const QPolygonF QGraphicsItem::mapToParent(const QPolygonF & amp;polygon) const QPainterPath QGraphicsItem::mapToParent(const QPainterPath & amp;path) const QPointF QGraphicsItem::mapToParent(qreal x, qreal y) const//Map a point within this graphic item to the scene coordinate system
QPointF QGraphicsItem::mapToScene(const QPointF & amp;point) const QPolygonF QGraphicsItem::mapToScene(const QRectF & amp;rect) const QPolygonF QGraphicsItem::mapToScene(const QPolygonF & amp;polygon) const QPainterPath QGraphicsItem::mapToScene(const QPainterPath & amp;path) const QPointF QGraphicsItem::mapToScene(qreal x, qreal y) const QPolygonF QGraphicsItem::mapToScene(qreal x, qreal y, qreal w, qreal h) const
4. Overall project structure
4.1 Classes used in the project
Project summary:
Some problems encountered on the project:
1. When I start adding a canvas to the tabWidget, I cannot draw. After selecting the graphics to draw, the program crashes and exits as soon as I click the brush. Then I added some judgment conditions. If tabWidget->currentIndex() < 0, the pointer is assigned a value. It failed. Later, after adding a judgment condition, it worked. Then I directly improved it. When the application window is opened, the canvas will be created on the tabWidget.
2. In mainwindow.cpp, I rewrote the mouseDoubleClickEvent method. When double-clicking the graphic, the property list on the right is updated. However, the program will crash when double-clicking the blank view. The solution used later is to add a judgment condition. If If the graphic has been selected, double-clicking the graphic will update the attribute list. If the graphic is not selected, simply double-clicking the canvas will ignore the event. The specific code implementation is as follows:
//Double-click the graphic to update the graphic’s attribute list void MainWindow::mouseDoubleClickEvent(QMouseEvent *event) { QGraphicsScene * scene = m_scene; if (scene & amp; & amp; !scene->selectedItems().isEmpty()) { if (scene->selectedItems().first()->isSelected()) { updateItemProperty(); //Update property list } }else{ event->ignore(); } }
3. When pressing the following button, if the graphic is not selected, the program will crash and crash. Later, I added some judgment conditions. For example, operations such as combination, alignment, and stretching can only be performed when the selected graphic is greater than 1. This problem Also a perfect solution
void MainWindow::aglin() { graphicsScene * scene = dynamic_cast<graphicsScene*>(m_scene); int selectedItemCount = scene->selectedItems().count(); if(ui->tabWidget->currentIndex() >= 0 & amp; & amp; scene & amp; & amp; 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); } } }
The above are some of the problems I encountered during development. Of course, there are also some minor problems, so I won’t elaborate on them one by one.