├── Draw_Figure.pro ├── README.md ├── bpointitem.cpp ├── bpointitem.h ├── bqgraphicsitem.cpp ├── bqgraphicsitem.h ├── bqgraphicsscene.cpp ├── bqgraphicsscene.h ├── bqgraphicsview.cpp ├── bqgraphicsview.h ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h └── mainwindow.ui /Draw_Figure.pro: -------------------------------------------------------------------------------- 1 | QT += core gui 2 | 3 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 4 | 5 | CONFIG += c++11 debug_and_release 6 | 7 | # The following define makes your compiler emit warnings if you use 8 | # any Qt feature that has been marked deprecated (the exact warnings 9 | # depend on your compiler). Please consult the documentation of the 10 | # deprecated API in order to know how to port your code away from it. 11 | DEFINES += QT_DEPRECATED_WARNINGS 12 | 13 | # You can also make your code fail to compile if it uses deprecated APIs. 14 | # In order to do so, uncomment the following line. 15 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 16 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 17 | 18 | SOURCES += \ 19 | bpointitem.cpp \ 20 | bqgraphicsitem.cpp \ 21 | bqgraphicsscene.cpp \ 22 | bqgraphicsview.cpp \ 23 | main.cpp \ 24 | mainwindow.cpp 25 | 26 | HEADERS += \ 27 | bpointitem.h \ 28 | bqgraphicsitem.h \ 29 | bqgraphicsscene.h \ 30 | bqgraphicsview.h \ 31 | mainwindow.h 32 | 33 | FORMS += \ 34 | mainwindow.ui 35 | 36 | # Default rules for deployment. 37 | qnx: target.path = /tmp/$${TARGET}/bin 38 | else: unix:!android: target.path = /opt/$${TARGET}/bin 39 | !isEmpty(target.path): INSTALLS += target 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Draw_Figure 2 | -------------------------------------------------------------------------------- /bpointitem.cpp: -------------------------------------------------------------------------------- 1 | #include "bpointitem.h" 2 | #include "bqgraphicsitem.h" 3 | 4 | BPointItem::BPointItem(QAbstractGraphicsShapeItem* parent, QPointF p, PointType type) 5 | : QAbstractGraphicsShapeItem(parent) 6 | , m_point(p) 7 | , m_type(type) 8 | { 9 | this->setPos(m_point); 10 | this->setFlags(QGraphicsItem::ItemIsSelectable | 11 | QGraphicsItem::ItemIsMovable | 12 | QGraphicsItem::ItemIsFocusable); 13 | 14 | switch (type) { 15 | case Center: 16 | this->setCursor(Qt::OpenHandCursor); 17 | break; 18 | case Edge: 19 | this->setCursor(Qt::PointingHandCursor); 20 | break; 21 | case Special: 22 | this->setCursor(Qt::PointingHandCursor); 23 | break; 24 | default: break; 25 | } 26 | } 27 | 28 | QRectF BPointItem::boundingRect() const 29 | { 30 | return QRectF(-4, -4, 8, 8); 31 | } 32 | 33 | void BPointItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 34 | { 35 | Q_UNUSED(option); 36 | Q_UNUSED(widget); 37 | painter->setPen(this->pen()); 38 | painter->setBrush(this->brush()); 39 | this->setPos(m_point); 40 | 41 | switch (m_type) { 42 | case Center: 43 | painter->drawEllipse(-4, -4, 8, 8); 44 | break; 45 | case Edge: 46 | painter->drawRect(QRectF(-4, -4, 8, 8)); 47 | break; 48 | case Special: 49 | painter->drawRect(QRectF(-4, -4, 8, 8)); 50 | break; 51 | default: break; 52 | } 53 | } 54 | 55 | void BPointItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) 56 | { 57 | if ( event->buttons() == Qt::LeftButton ) { 58 | qreal dx = event->scenePos().x() - event->lastScenePos().x(); 59 | qreal dy = event->scenePos().y() - event->lastScenePos().y(); 60 | 61 | BGraphicsItem* item = static_cast(this->parentItem()); 62 | BGraphicsItem::ItemType itemType = item->getType(); 63 | 64 | switch (m_type) { 65 | case Center: { 66 | item->moveBy(dx, dy); 67 | this->scene()->update(); 68 | } break; 69 | case Edge: { 70 | if (itemType != BGraphicsItem::ItemType::Rounded_Rectangle) { 71 | m_point = this->mapToParent( event->pos() ); 72 | this->setPos(m_point); 73 | this->scene()->update(); 74 | } 75 | 76 | switch (itemType) { 77 | case BGraphicsItem::ItemType::Ellipse: { 78 | BEllipse *ellipse = dynamic_cast(item); 79 | ellipse->setEdge(m_point); 80 | } break; 81 | case BGraphicsItem::ItemType::Circle: { 82 | BCircle *circle = dynamic_cast(item); 83 | circle->setEdge(m_point); 84 | circle->updateRadius(); 85 | } break; 86 | case BGraphicsItem::ItemType::Concentric_Circle: { 87 | BCircle *circle = dynamic_cast(item); 88 | circle->setEdge(m_point); 89 | circle->updateRadius(); 90 | } break; 91 | case BGraphicsItem::ItemType::Pie: { 92 | BPie *pie = dynamic_cast(item); 93 | pie->setEdge(m_point); 94 | pie->updateRadius(); 95 | pie->updateAngle(); 96 | } break; 97 | case BGraphicsItem::ItemType::Chord: { 98 | BChord *chord = dynamic_cast(item); 99 | chord->setEdge(m_point); 100 | chord->updateRadius(); 101 | chord->updateEndAngle(); 102 | } break; 103 | case BGraphicsItem::ItemType::Rectangle: { 104 | BRectangle *rectangle = dynamic_cast(item); 105 | rectangle->setEdge(m_point); 106 | } break; 107 | case BGraphicsItem::ItemType::Square: { 108 | BSquare *square = dynamic_cast(item); 109 | qreal ret = m_point.x() > m_point.y() ? m_point.x() : m_point.y(); 110 | m_point.setX(ret); 111 | m_point.setY(ret); 112 | square->setEdge(m_point); 113 | } break; 114 | case BGraphicsItem::ItemType::Polygon: { 115 | BPolygon *polygon = dynamic_cast(item); 116 | polygon->updatePolygon(QPointF(event->lastScenePos().x(), event->lastScenePos().y()), 117 | QPointF(event->scenePos().x(), event->scenePos().y())); 118 | } break; 119 | case BGraphicsItem::ItemType::Round_End_Rectangle: { 120 | BRound_End_Rectangle *round_End_Rectangle = dynamic_cast(item); 121 | round_End_Rectangle->setEdge(m_point); 122 | } break; 123 | case BGraphicsItem::ItemType::Rounded_Rectangle: { 124 | BRounded_Rectangle *rounded_Rectangle = dynamic_cast(item); 125 | 126 | m_point = this->mapToParent( event->pos() ); 127 | 128 | if (m_point.x() <= rounded_Rectangle->getRadius()) { 129 | m_point.setX( rounded_Rectangle->getRadius() ); 130 | } 131 | if (m_point.y() <= rounded_Rectangle->getRadius()) { 132 | m_point.setY( rounded_Rectangle->getRadius() ); 133 | } 134 | 135 | this->setPos(m_point); 136 | this->scene()->update(); 137 | 138 | QPointF p = rounded_Rectangle->getEdge(); 139 | rounded_Rectangle->setEdge(m_point); 140 | rounded_Rectangle->updateAnotherEdge(p); 141 | } break; 142 | default: break; 143 | } 144 | } break; 145 | case Special: { 146 | switch (itemType) { 147 | case BGraphicsItem::ItemType::Concentric_Circle: { 148 | m_point = this->mapToParent( event->pos() ); 149 | this->setPos(m_point); 150 | this->scene()->update(); 151 | 152 | BConcentricCircle *conCircle = dynamic_cast(item); 153 | conCircle->setAnotherEdge(m_point); 154 | conCircle->updateOtherRadius(); 155 | } break; 156 | case BGraphicsItem::ItemType::Rounded_Rectangle: { 157 | BRounded_Rectangle *rounded_Rectangle = dynamic_cast(item); 158 | 159 | qreal retX = 0; 160 | qreal retY = 0; 161 | 162 | if ( rounded_Rectangle->getEdge().x() == rounded_Rectangle->getAnotherEdge().x() && 163 | (-1) * rounded_Rectangle->getEdge().y() != rounded_Rectangle->getAnotherEdge().y() ) 164 | { 165 | retX = rounded_Rectangle->getAnotherEdge().x(); 166 | retY = rounded_Rectangle->getAnotherEdge().y() + dy; 167 | } 168 | else if ( rounded_Rectangle->getEdge().x() != rounded_Rectangle->getAnotherEdge().x() && 169 | (-1) * rounded_Rectangle->getEdge().y() == rounded_Rectangle->getAnotherEdge().y() ) 170 | { 171 | retX = rounded_Rectangle->getAnotherEdge().x() + dx; 172 | retY = rounded_Rectangle->getAnotherEdge().y(); 173 | } 174 | else if ( rounded_Rectangle->getEdge().x() == rounded_Rectangle->getAnotherEdge().x() && 175 | (-1) * rounded_Rectangle->getEdge().y() == rounded_Rectangle->getAnotherEdge().y() ) 176 | { 177 | if ( abs(dx) >= abs(dy) ) { 178 | retX = rounded_Rectangle->getAnotherEdge().x() + dx; 179 | retY = rounded_Rectangle->getAnotherEdge().y(); 180 | } else { 181 | retX = rounded_Rectangle->getAnotherEdge().x(); 182 | retY = rounded_Rectangle->getAnotherEdge().y() + dy; 183 | } 184 | } 185 | 186 | if ( retX > rounded_Rectangle->getEdge().x() ) { 187 | retX = rounded_Rectangle->getEdge().x(); 188 | } else if ( retX < 0 ) { 189 | retX = 0; 190 | } 191 | 192 | if ( retY < (-1) * rounded_Rectangle->getEdge().y() ) { 193 | retY = (-1) * rounded_Rectangle->getEdge().y(); 194 | } else if ( retY > 0 ) { 195 | retY = 0; 196 | } 197 | 198 | m_point.setX(retX); 199 | m_point.setY(retY); 200 | this->setPos(m_point); 201 | this->scene()->update(); 202 | 203 | rounded_Rectangle->setAnotherEdge(m_point); 204 | rounded_Rectangle->updateRadius(); 205 | } 206 | default: break; 207 | } 208 | } break; 209 | default: break; 210 | } 211 | } 212 | } 213 | 214 | //------------------------------------------------------------------------------ 215 | 216 | void BPointItemList::setRandColor() 217 | { 218 | this->setColor(QColor(qrand()%256, qrand()%256, qrand()%256)); 219 | } 220 | 221 | void BPointItemList::setColor(const QColor color) 222 | { 223 | for (auto &temp : *this) 224 | { 225 | temp->setBrush(QBrush(color)); 226 | } 227 | } 228 | 229 | void BPointItemList::setVisible(bool visible) 230 | { 231 | for (auto &temp : *this) 232 | { 233 | temp->setVisible(visible); 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /bpointitem.h: -------------------------------------------------------------------------------- 1 | #ifndef BPOINTITEM_H 2 | #define BPOINTITEM_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | // 自定义功能图元 - 点 16 | class BPointItem : public QObject, public QAbstractGraphicsShapeItem 17 | { 18 | Q_OBJECT 19 | 20 | public: 21 | enum PointType { 22 | Center = 0, // 中心点 23 | Edge, // 边缘点(可拖动改变图形的形状、大小) 24 | Special // 特殊功能点 25 | }; 26 | 27 | BPointItem(QAbstractGraphicsShapeItem* parent, QPointF p, PointType type); 28 | 29 | QPointF getPoint() { return m_point; } 30 | void setPoint(QPointF p) { m_point = p; } 31 | 32 | protected: 33 | virtual QRectF boundingRect() const override; 34 | 35 | virtual void paint(QPainter *painter, 36 | const QStyleOptionGraphicsItem *option, 37 | QWidget *widget) override; 38 | 39 | virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; 40 | 41 | public: 42 | QPointF m_point; 43 | PointType m_type; 44 | }; 45 | 46 | //------------------------------------------------------------------------------ 47 | 48 | // 存放点的容器 49 | class BPointItemList: public QList 50 | { 51 | public: 52 | void setRandColor(); 53 | void setColor(const QColor color); 54 | void setVisible(bool visible); 55 | }; 56 | 57 | #endif // BPOINTITEM_H 58 | -------------------------------------------------------------------------------- /bqgraphicsitem.cpp: -------------------------------------------------------------------------------- 1 | #include "bqgraphicsitem.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | BGraphicsItem::BGraphicsItem(QPointF center, QPointF edge, ItemType type) 9 | : m_center(center), m_edge(edge), m_type(type) 10 | { 11 | m_pen_noSelected.setColor(QColor(0, 160, 230)); 12 | m_pen_noSelected.setWidth(2); 13 | m_pen_isSelected.setColor(QColor(255, 0, 255)); 14 | m_pen_isSelected.setWidth(2); 15 | 16 | this->setPen(m_pen_noSelected); 17 | this->setFlags(QGraphicsItem::ItemIsSelectable | 18 | QGraphicsItem::ItemIsMovable | 19 | QGraphicsItem::ItemIsFocusable); 20 | } 21 | 22 | void BGraphicsItem::focusInEvent(QFocusEvent *event) 23 | { 24 | Q_UNUSED(event); 25 | this->setPen(m_pen_isSelected); 26 | } 27 | 28 | void BGraphicsItem::focusOutEvent(QFocusEvent *event) 29 | { 30 | Q_UNUSED(event); 31 | this->setPen(m_pen_noSelected); 32 | } 33 | 34 | //------------------------------------------------------------------------------ 35 | 36 | BEllipse::BEllipse(qreal x, qreal y, qreal width, qreal height, ItemType type) 37 | : BGraphicsItem(QPointF(x,y), QPointF(x+width/2,y+height/2), type) 38 | { 39 | BPointItem *point = new BPointItem(this, m_edge, BPointItem::Edge); 40 | point->setParentItem(this); 41 | m_pointList.append(point); 42 | m_pointList.append(new BPointItem(this, m_center, BPointItem::Center)); 43 | m_pointList.setRandColor(); 44 | } 45 | 46 | QRectF BEllipse::boundingRect() const 47 | { 48 | return QRectF(m_center.x() - abs(m_edge.x()), m_center.y() - abs(m_edge.y()), abs(m_edge.x()) * 2, abs(m_edge.y()) * 2); 49 | } 50 | 51 | void BEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 52 | { 53 | Q_UNUSED(option); 54 | Q_UNUSED(widget); 55 | painter->setPen(this->pen()); 56 | painter->setBrush(this->brush()); 57 | 58 | QRectF ret(m_center.x() - abs(m_edge.x()), m_center.y() - abs(m_edge.y()), abs(m_edge.x()) * 2, abs(m_edge.y()) * 2); 59 | painter->drawEllipse(ret); 60 | } 61 | 62 | void BEllipse::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) 63 | { 64 | if ( !this->isSelected() ) 65 | return; 66 | 67 | QMenu* menu = new QMenu(); 68 | menu->setStyleSheet("QMenu { background-color:rgb(89,87,87); border: 5px solid rgb(235,110,36); }"); 69 | 70 | QSpinBox* width_spinBox = new QSpinBox(menu); 71 | width_spinBox->setStyleSheet("QSpinBox{ width:120px; height:30px; font-size:16px; font-weight:bold; }"); 72 | width_spinBox->setRange(0, 1000); 73 | width_spinBox->setPrefix("w: "); 74 | width_spinBox->setSuffix(" mm"); 75 | width_spinBox->setSingleStep(1); 76 | width_spinBox->setValue(2 * abs(m_edge.x())); 77 | connect(width_spinBox, static_cast(&QSpinBox::valueChanged), [=](int v){ 78 | if (m_edge.x() < 0) { 79 | m_edge.setX((-1) * v/2); 80 | } else { 81 | m_edge.setX(v/2); 82 | } 83 | m_pointList.at(0)->setPoint(m_edge); 84 | this->hide(); 85 | this->update(); 86 | this->show(); 87 | }); 88 | 89 | QSpinBox* height__spinBox = new QSpinBox(menu); 90 | height__spinBox->setStyleSheet("QSpinBox{ width:120px; height:30px; font-size:16px; font-weight:bold; }"); 91 | height__spinBox->setRange(0, 1000); 92 | height__spinBox->setPrefix("h: "); 93 | height__spinBox->setSuffix(" mm"); 94 | height__spinBox->setSingleStep(1); 95 | height__spinBox->setValue(2 * abs(m_edge.y())); 96 | connect(height__spinBox, static_cast(&QSpinBox::valueChanged), [=](int v){ 97 | if (m_edge.y() < 0) { 98 | m_edge.setY((-1) * v/2); 99 | } else { 100 | m_edge.setY(v/2); 101 | } 102 | m_pointList.at(0)->setPoint(m_edge); 103 | this->hide(); 104 | this->update(); 105 | this->show(); 106 | }); 107 | 108 | QWidgetAction* width_widgetAction = new QWidgetAction(menu); 109 | width_widgetAction->setDefaultWidget(width_spinBox); 110 | menu->addAction(width_widgetAction); 111 | 112 | QWidgetAction* height_widgetAction = new QWidgetAction(menu); 113 | height_widgetAction->setDefaultWidget(height__spinBox); 114 | menu->addAction(height_widgetAction); 115 | 116 | menu->exec(QCursor::pos()); 117 | delete menu; 118 | 119 | QGraphicsItem::contextMenuEvent(event); 120 | } 121 | 122 | //------------------------------------------------------------------------------ 123 | 124 | BCircle::BCircle(qreal x, qreal y, qreal radius, ItemType type) 125 | : BEllipse(x, y, radius*sqrt(2), radius*sqrt(2), type) 126 | { 127 | updateRadius(); 128 | } 129 | 130 | void BCircle::updateRadius() 131 | { 132 | m_radius = sqrt(pow(m_center.x() - m_edge.x(), 2) + pow(m_center.y() - m_edge.y(), 2)); 133 | } 134 | 135 | QRectF BCircle::boundingRect() const 136 | { 137 | return QRectF(m_center.x() - m_radius, m_center.y() - m_radius, m_radius * 2, m_radius * 2); 138 | } 139 | 140 | void BCircle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 141 | { 142 | Q_UNUSED(option); 143 | Q_UNUSED(widget); 144 | painter->setPen(this->pen()); 145 | painter->setBrush(this->brush()); 146 | 147 | QRectF ret(m_center.x() - m_radius, m_center.y() - m_radius, m_radius * 2, m_radius * 2); 148 | painter->drawEllipse(ret); 149 | } 150 | 151 | void BCircle::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) 152 | { 153 | if ( !this->isSelected() ) 154 | return; 155 | 156 | QMenu* menu = new QMenu(); 157 | menu->setStyleSheet("QMenu { background-color:rgb(89,87,87); border: 5px solid rgb(235,110,36); }"); 158 | 159 | QSpinBox* radius_spinBox = new QSpinBox(menu); 160 | radius_spinBox->setStyleSheet("QSpinBox{ width:120px; height:30px; font-size:16px; font-weight:bold; }"); 161 | radius_spinBox->setRange(0, 1000); 162 | radius_spinBox->setPrefix("r: "); 163 | radius_spinBox->setSuffix(" mm"); 164 | radius_spinBox->setSingleStep(1); 165 | radius_spinBox->setValue(m_radius); 166 | connect(radius_spinBox, static_cast(&QSpinBox::valueChanged), [=](int v){ 167 | m_radius = v; 168 | 169 | if (m_edge.x() < 0) { 170 | m_edge.setX(m_center.x() - m_radius * sqrt(2)/2); 171 | } else { 172 | m_edge.setX(m_center.x() + m_radius * sqrt(2)/2); 173 | } 174 | 175 | if (m_edge.y() < 0) { 176 | m_edge.setY(m_center.y() - m_radius * sqrt(2)/2); 177 | } else { 178 | m_edge.setY(m_center.y() + m_radius * sqrt(2)/2); 179 | } 180 | 181 | m_pointList.at(0)->setPoint(m_edge); 182 | this->hide(); 183 | this->update(); 184 | this->show(); 185 | }); 186 | 187 | QWidgetAction* radius_widgetAction = new QWidgetAction(menu); 188 | radius_widgetAction->setDefaultWidget(radius_spinBox); 189 | menu->addAction(radius_widgetAction); 190 | 191 | menu->exec(QCursor::pos()); 192 | delete menu; 193 | 194 | QGraphicsItem::contextMenuEvent(event); 195 | } 196 | 197 | //------------------------------------------------------------------------------ 198 | 199 | BConcentricCircle::BConcentricCircle(qreal x, qreal y, qreal radius1, qreal radius2, ItemType type) 200 | : BCircle(x, y, radius1, type), m_another_edge(x+radius2*sqrt(2)/2, y+radius2*sqrt(2)/2) 201 | { 202 | BPointItem *point = new BPointItem(this, m_another_edge, BPointItem::Special); 203 | point->setParentItem(this); 204 | m_pointList.append(point); 205 | m_pointList.setRandColor(); 206 | 207 | updateOtherRadius(); 208 | } 209 | 210 | void BConcentricCircle::updateOtherRadius() 211 | { 212 | m_another_radius = sqrt(pow(m_center.x() - m_another_edge.x(), 2) + 213 | pow(m_center.y() - m_another_edge.y(), 2)); 214 | } 215 | 216 | void BConcentricCircle::setAnotherEdge(QPointF p) 217 | { 218 | m_another_edge = p; 219 | } 220 | 221 | QRectF BConcentricCircle::boundingRect() const 222 | { 223 | qreal temp = m_radius > m_another_radius ? m_radius : m_another_radius; 224 | return QRectF(m_center.x() - temp, m_center.y() - temp, temp * 2, temp * 2); 225 | } 226 | 227 | void BConcentricCircle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 228 | { 229 | painter->setPen(this->pen()); 230 | painter->setBrush(this->brush()); 231 | 232 | QRectF ret(m_center.x() - m_another_radius, m_center.y() - m_another_radius, m_another_radius * 2, m_another_radius * 2); 233 | painter->drawEllipse(ret); 234 | 235 | BCircle::paint(painter, option, widget); 236 | } 237 | 238 | void BConcentricCircle::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) 239 | { 240 | if ( !this->isSelected() ) 241 | return; 242 | 243 | QMenu* menu = new QMenu(); 244 | menu->setStyleSheet("QMenu { background-color:rgb(89,87,87); border: 5px solid rgb(235,110,36); }"); 245 | 246 | QSpinBox* radius_spinBox = new QSpinBox(menu); 247 | radius_spinBox->setStyleSheet("QSpinBox{ width:120px; height:30px; font-size:16px; font-weight:bold; }"); 248 | radius_spinBox->setRange(0, 1000); 249 | radius_spinBox->setPrefix("r1: "); 250 | radius_spinBox->setSuffix(" mm"); 251 | radius_spinBox->setSingleStep(1); 252 | radius_spinBox->setValue(m_radius); 253 | connect(radius_spinBox, static_cast(&QSpinBox::valueChanged), [=](int v){ 254 | m_radius = v; 255 | 256 | if (m_edge.x() < 0) { 257 | m_edge.setX(m_center.x() - m_radius * sqrt(2)/2); 258 | } else { 259 | m_edge.setX(m_center.x() + m_radius * sqrt(2)/2); 260 | } 261 | 262 | if (m_edge.y() < 0) { 263 | m_edge.setY(m_center.y() - m_radius * sqrt(2)/2); 264 | } else { 265 | m_edge.setY(m_center.y() + m_radius * sqrt(2)/2); 266 | } 267 | 268 | m_pointList.at(0)->setPoint(m_edge); 269 | this->hide(); 270 | this->update(); 271 | this->show(); 272 | }); 273 | 274 | QSpinBox* another_radius_spinBox = new QSpinBox(menu); 275 | another_radius_spinBox->setStyleSheet("QSpinBox{ width:120px; height:30px; font-size:16px; font-weight:bold; }"); 276 | another_radius_spinBox->setRange(0, 1000); 277 | another_radius_spinBox->setPrefix("r2: "); 278 | another_radius_spinBox->setSuffix(" mm"); 279 | another_radius_spinBox->setSingleStep(1); 280 | another_radius_spinBox->setValue(m_another_radius); 281 | connect(another_radius_spinBox, static_cast(&QSpinBox::valueChanged), [=](int v){ 282 | m_another_radius = v; 283 | 284 | if (m_another_edge.x() < 0) { 285 | m_another_edge.setX(m_center.x() - m_another_radius * sqrt(2)/2); 286 | } else { 287 | m_another_edge.setX(m_center.x() + m_another_radius * sqrt(2)/2); 288 | } 289 | 290 | if (m_another_edge.y() < 0) { 291 | m_another_edge.setY(m_center.y() - m_another_radius * sqrt(2)/2); 292 | } else { 293 | m_another_edge.setY(m_center.y() + m_another_radius * sqrt(2)/2); 294 | } 295 | 296 | m_pointList.at(2)->setPoint(m_another_edge); 297 | this->hide(); 298 | this->update(); 299 | this->show(); 300 | }); 301 | 302 | QWidgetAction* radius_widgetAction = new QWidgetAction(menu); 303 | radius_widgetAction->setDefaultWidget(radius_spinBox); 304 | menu->addAction(radius_widgetAction); 305 | 306 | QWidgetAction* another_radius_widgetAction = new QWidgetAction(menu); 307 | another_radius_widgetAction->setDefaultWidget(another_radius_spinBox); 308 | menu->addAction(another_radius_widgetAction); 309 | 310 | menu->exec(QCursor::pos()); 311 | delete menu; 312 | 313 | QGraphicsItem::contextMenuEvent(event); 314 | } 315 | 316 | //------------------------------------------------------------------------------ 317 | 318 | BPie::BPie(qreal x, qreal y, qreal radius, qreal angle, ItemType type) 319 | : BCircle(x, y, radius, type), m_angle(angle) 320 | { 321 | if ( (angle >= 0 && angle < 90) || (angle >= 270 && angle < 360) ) 322 | { 323 | m_edge.setX( m_center.x() + radius * cos(angle/180*PI) ); 324 | m_edge.setY( m_center.y() + radius * sin(angle/180*PI) * (-1) ); 325 | } 326 | else if ( (angle >= 90 && angle < 270) ) 327 | { 328 | m_edge.setY( m_center.y() + radius * sin(angle/180*PI) * (-1) ); 329 | m_edge.setX( m_center.x() + radius * cos(angle/180*PI) ); 330 | } 331 | 332 | m_pointList.at(0)->setPoint(m_edge); 333 | m_radius = radius; 334 | } 335 | 336 | void BPie::updateAngle() 337 | { 338 | qreal dx = m_edge.x() - m_center.x(); 339 | qreal dy = m_edge.y() - m_center.y(); 340 | 341 | if ( dx >= 0 && dy < 0 ) 342 | { 343 | m_angle = atan2( (-1)*(dy), dx ) *180/PI; 344 | } 345 | else if ( dx < 0 && dy < 0 ) 346 | { 347 | m_angle = atan2( (-1)*dy, dx ) *180/PI; 348 | } 349 | else if ( dx < 0 && dy >= 0 ) 350 | { 351 | m_angle = 360 + atan2( (-1)*dy, dx ) *180/PI; 352 | } 353 | else if ( dx >= 0 && dy >= 0 ) 354 | { 355 | m_angle = 360 - atan2( dy, dx ) *180/PI; 356 | } 357 | } 358 | 359 | void BPie::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 360 | { 361 | Q_UNUSED(option); 362 | Q_UNUSED(widget); 363 | painter->setPen(this->pen()); 364 | painter->setBrush(this->brush()); 365 | 366 | QRectF ret(m_center.x() - m_radius, m_center.y() - m_radius, m_radius * 2, m_radius * 2); 367 | painter->drawPie(ret, 16*0, 16*(m_angle)); 368 | } 369 | 370 | //------------------------------------------------------------------------------ 371 | 372 | BChord::BChord(qreal x, qreal y, qreal radius, qreal angle, ItemType type) 373 | : BPie(x, y, radius, angle, type) 374 | { 375 | updateEndAngle(); 376 | } 377 | 378 | void BChord::updateEndAngle() 379 | { 380 | qreal dx = m_edge.x() - m_center.x(); 381 | qreal dy = m_edge.y() - m_center.y(); 382 | 383 | if ( dx >= 0 && dy < 0 ) 384 | { 385 | m_angle = atan2( (-1)*(dy), dx ) *180/PI; 386 | } 387 | else if ( dx < 0 && dy < 0 ) 388 | { 389 | m_angle = 180 - atan2( (-1)*dy, dx ) *180/PI; 390 | } 391 | else if ( dx < 0 && dy >= 0 ) 392 | { 393 | m_angle = 360 + atan2( (-1)*dy, dx ) *180/PI; 394 | } 395 | else if ( dx >= 0 && dy >= 0 ) 396 | { 397 | m_angle = atan2( (-1)*dy, dx ) *180/PI; 398 | } 399 | 400 | m_end_angle = 180 - m_angle*2; 401 | } 402 | 403 | void BChord::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 404 | { 405 | Q_UNUSED(option); 406 | Q_UNUSED(widget); 407 | painter->setPen(this->pen()); 408 | painter->setBrush(this->brush()); 409 | 410 | QRectF ret(m_center.x() - m_radius, m_center.y() - m_radius, m_radius * 2, m_radius * 2); 411 | painter->drawChord(ret, 16*(m_angle), 16*(m_end_angle)); 412 | } 413 | 414 | //------------------------------------------------------------------------------ 415 | 416 | BRectangle::BRectangle(qreal x, qreal y, qreal width, qreal height, ItemType type) 417 | : BGraphicsItem(QPointF(x,y), QPointF(width/2,height/2), type) 418 | { 419 | BPointItem *point = new BPointItem(this, m_edge, BPointItem::Edge); 420 | point->setParentItem(this); 421 | m_pointList.append(point); 422 | m_pointList.append(new BPointItem(this, m_center, BPointItem::Center)); 423 | m_pointList.setRandColor(); 424 | } 425 | 426 | QRectF BRectangle::boundingRect() const 427 | { 428 | return QRectF(m_center.x() - abs(m_edge.x()), m_center.y() - abs(m_edge.y()), abs(m_edge.x()) * 2, abs(m_edge.y()) * 2); 429 | } 430 | 431 | void BRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 432 | { 433 | Q_UNUSED(option); 434 | Q_UNUSED(widget); 435 | painter->setPen(this->pen()); 436 | painter->setBrush(this->brush()); 437 | 438 | QRectF ret(m_center.x() - abs(m_edge.x()), m_center.y() - abs(m_edge.y()), abs(m_edge.x()) * 2, abs(m_edge.y()) * 2); 439 | painter->drawRect(ret); 440 | } 441 | 442 | void BRectangle::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) 443 | { 444 | if ( !this->isSelected() ) 445 | return; 446 | 447 | QMenu* menu = new QMenu(); 448 | menu->setStyleSheet("QMenu { background-color:rgb(89,87,87); border: 5px solid rgb(235,110,36); }"); 449 | 450 | QSpinBox* width_spinBox = new QSpinBox(menu); 451 | width_spinBox->setStyleSheet("QSpinBox{ width:120px; height:30px; font-size:16px; font-weight:bold; }"); 452 | width_spinBox->setRange(0, 1000); 453 | width_spinBox->setPrefix("w: "); 454 | width_spinBox->setSuffix(" mm"); 455 | width_spinBox->setSingleStep(1); 456 | width_spinBox->setValue(2 * abs(m_edge.x())); 457 | connect(width_spinBox, static_cast(&QSpinBox::valueChanged), [=](int v){ 458 | if (m_edge.x() < 0) { 459 | m_edge.setX((-1) * v/2); 460 | } else { 461 | m_edge.setX(v/2); 462 | } 463 | m_pointList.at(0)->setPoint(m_edge); 464 | this->hide(); 465 | this->update(); 466 | this->show(); 467 | }); 468 | 469 | QSpinBox* height__spinBox = new QSpinBox(menu); 470 | height__spinBox->setStyleSheet("QSpinBox{ width:120px; height:30px; font-size:16px; font-weight:bold; }"); 471 | height__spinBox->setRange(0, 1000); 472 | height__spinBox->setPrefix("h: "); 473 | height__spinBox->setSuffix(" mm"); 474 | height__spinBox->setSingleStep(1); 475 | height__spinBox->setValue(2 * abs(m_edge.y())); 476 | connect(height__spinBox, static_cast(&QSpinBox::valueChanged), [=](int v){ 477 | if (m_edge.y() < 0) { 478 | m_edge.setY((-1) * v/2); 479 | } else { 480 | m_edge.setY(v/2); 481 | } 482 | m_pointList.at(0)->setPoint(m_edge); 483 | this->hide(); 484 | this->update(); 485 | this->show(); 486 | }); 487 | 488 | QWidgetAction* width_widgetAction = new QWidgetAction(menu); 489 | width_widgetAction->setDefaultWidget(width_spinBox); 490 | menu->addAction(width_widgetAction); 491 | 492 | QWidgetAction* height_widgetAction = new QWidgetAction(menu); 493 | height_widgetAction->setDefaultWidget(height__spinBox); 494 | menu->addAction(height_widgetAction); 495 | 496 | menu->exec(QCursor::pos()); 497 | delete menu; 498 | 499 | QGraphicsItem::contextMenuEvent(event); 500 | } 501 | 502 | //------------------------------------------------------------------------------ 503 | 504 | BSquare::BSquare(qreal x, qreal y, qreal width, ItemType type) 505 | : BRectangle(x, y, width, width, type) {} 506 | 507 | void BSquare::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) 508 | { 509 | if ( !this->isSelected() ) 510 | return; 511 | 512 | QMenu* menu = new QMenu(); 513 | menu->setStyleSheet("QMenu { background-color:rgb(89,87,87); border: 5px solid rgb(235,110,36); }"); 514 | 515 | QSpinBox* distance_spinBox = new QSpinBox(menu); 516 | distance_spinBox->setStyleSheet("QSpinBox{ width:120px; height:30px; font-size:16px; font-weight:bold; }"); 517 | distance_spinBox->setRange(0, 1000); 518 | distance_spinBox->setPrefix("d: "); 519 | distance_spinBox->setSuffix(" mm"); 520 | distance_spinBox->setSingleStep(1); 521 | distance_spinBox->setValue(2 * abs(m_edge.x())); 522 | connect(distance_spinBox, static_cast(&QSpinBox::valueChanged), [=](int v){ 523 | if (m_edge.x() < 0) { 524 | m_edge.setX((-1) * v/2); 525 | m_edge.setY((-1) * v/2); 526 | } else { 527 | m_edge.setX(v/2); 528 | m_edge.setY(v/2); 529 | } 530 | m_pointList.at(0)->setPoint(m_edge); 531 | this->hide(); 532 | this->update(); 533 | this->show(); 534 | }); 535 | 536 | QWidgetAction* distance_widgetAction = new QWidgetAction(menu); 537 | distance_widgetAction->setDefaultWidget(distance_spinBox); 538 | menu->addAction(distance_widgetAction); 539 | 540 | menu->exec(QCursor::pos()); 541 | delete menu; 542 | 543 | QGraphicsItem::contextMenuEvent(event); 544 | } 545 | 546 | //------------------------------------------------------------------------------ 547 | 548 | BPolygon::BPolygon(ItemType type) 549 | : BGraphicsItem(QPointF(0,0), QPointF(0,0), type) 550 | { 551 | is_create_finished = false; 552 | } 553 | 554 | void BPolygon::pushPoint(QPointF p, QList list, bool isCenter) 555 | { 556 | if (!is_create_finished) { 557 | m_center = getCentroid(list); 558 | getMaxLength(); 559 | 560 | if (isCenter) { 561 | m_pointList.append(new BPointItem(this, m_center, BPointItem::Center)); 562 | m_pointList.setRandColor(); 563 | is_create_finished = true; 564 | } else { 565 | BPointItem *point = new BPointItem(this, p, BPointItem::Edge); 566 | point->setParentItem(this); 567 | m_pointList.append(point); 568 | m_pointList.setColor(QColor(0, 255, 0)); 569 | } 570 | 571 | this->update(); 572 | } 573 | } 574 | 575 | QPointF BPolygon::getCentroid(QList list) 576 | { 577 | qreal x = 0; 578 | qreal y = 0; 579 | for (auto &temp : list) 580 | { 581 | x += temp.x(); 582 | y += temp.y(); 583 | } 584 | x = x/list.size(); 585 | y = y/list.size(); 586 | return QPointF(x,y); 587 | } 588 | 589 | void BPolygon::getMaxLength() 590 | { 591 | QVector vec; 592 | for (auto &temp : m_pointList) 593 | { 594 | qreal dis = sqrt(pow(m_center.x() - temp->x(), 2) + pow(m_center.y() - temp->y(), 2)); 595 | vec.append(dis); 596 | } 597 | 598 | qreal ret = 0; 599 | for (auto &temp : vec) 600 | { 601 | if (temp > ret) { 602 | ret = temp; 603 | } 604 | } 605 | m_radius = ret; 606 | } 607 | 608 | void BPolygon::updatePolygon(QPointF origin, QPointF end) 609 | { 610 | QList list; 611 | 612 | for (auto &temp : m_pointList) { 613 | if (temp->getPoint() == origin) { 614 | temp->setPoint(end); 615 | } 616 | list.append(temp->getPoint()); 617 | } 618 | 619 | m_center = getCentroid(list); 620 | m_pointList.at(m_pointList.size()-1)->setPoint(m_center); 621 | 622 | getMaxLength(); 623 | } 624 | 625 | QRectF BPolygon::boundingRect() const 626 | { 627 | return QRectF(m_center.x() - m_radius, m_center.y() - m_radius, m_radius * 2, m_radius * 2); 628 | } 629 | 630 | void BPolygon::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 631 | { 632 | Q_UNUSED(option); 633 | Q_UNUSED(widget); 634 | painter->setPen(this->pen()); 635 | painter->setBrush(this->brush()); 636 | 637 | if (is_create_finished) { 638 | for (int i = 1; i < m_pointList.size() - 1; i++) 639 | { 640 | painter->drawLine(m_pointList.at(i-1)->getPoint(), m_pointList.at(i)->getPoint()); 641 | } 642 | 643 | painter->drawLine(m_pointList.at(m_pointList.size()-2)->getPoint(), m_pointList.at(0)->getPoint()); 644 | } else { 645 | for (int i = 1; i < m_pointList.size(); i++) 646 | { 647 | painter->drawLine(m_pointList.at(i-1)->getPoint(), m_pointList.at(i)->getPoint()); 648 | } 649 | } 650 | } 651 | 652 | //------------------------------------------------------------------------------ 653 | 654 | BRound_End_Rectangle::BRound_End_Rectangle(qreal x, qreal y, qreal width, qreal height, ItemType type) 655 | : BRectangle(x, y, width, height, type) {} 656 | 657 | QRectF BRound_End_Rectangle::boundingRect() const 658 | { 659 | QRectF ret = QRectF(m_center.x() - m_edge.x() - m_edge.y(), 660 | m_center.y() - m_edge.y(), 661 | abs(m_edge.x()) * 2 + abs(m_edge.y()) * 2, 662 | abs(m_edge.y()) * 2); 663 | 664 | if ( m_edge.x() >= 0 && m_edge.y() < 0 ) 665 | { 666 | ret.moveTo(m_center.x() - m_edge.x() + m_edge.y(), m_center.y() + m_edge.y()); 667 | } 668 | else if ( m_edge.x() < 0 && m_edge.y() < 0 ) 669 | { 670 | ret.moveTo(m_center.x() + m_edge.x() + m_edge.y(), m_center.y() + m_edge.y()); 671 | } 672 | else if ( m_edge.x() < 0 && m_edge.y() >= 0 ) 673 | { 674 | ret.moveTo(m_center.x() + m_edge.x() - m_edge.y(), m_center.y() - m_edge.y()); 675 | } 676 | else if ( m_edge.x() >= 0 && m_edge.y() >=0 ) 677 | { 678 | ret.moveTo(m_center.x() - m_edge.x() - m_edge.y(), m_center.y() - m_edge.y()); 679 | } 680 | 681 | return ret; 682 | } 683 | 684 | void BRound_End_Rectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 685 | { 686 | Q_UNUSED(option); 687 | Q_UNUSED(widget); 688 | painter->setPen(this->pen()); 689 | painter->setBrush(this->brush()); 690 | 691 | QPointF left_top, left_bottom, right_top, right_bottom; 692 | 693 | if ( m_edge.x() >= 0 && m_edge.y() < 0 ) 694 | { 695 | left_top = QPointF(m_center.x() - m_edge.x() + m_edge.y(), m_edge.y()); 696 | left_bottom = QPointF(m_center.x() - m_edge.x() + m_edge.y(), (-1) * m_edge.y()); 697 | right_top = QPointF(m_center.x() + m_edge.x() - m_edge.y(), m_edge.y()); 698 | right_bottom = QPointF(m_center.x() + m_edge.x() - m_edge.y(), (-1) * m_edge.y()); 699 | } 700 | else if ( m_edge.x() < 0 && m_edge.y() < 0 ) 701 | { 702 | left_top = QPointF(m_center.x() + m_edge.x() + m_edge.y(), m_edge.y()); 703 | left_bottom = QPointF(m_center.x() + m_edge.x() + m_edge.y(), (-1) * m_edge.y()); 704 | right_top = QPointF(m_center.x() - m_edge.x() - m_edge.y(), m_edge.y()); 705 | right_bottom = QPointF(m_center.x() - m_edge.x() - m_edge.y(), (-1) * m_edge.y()); 706 | } 707 | else if ( m_edge.x() < 0 && m_edge.y() >= 0 ) 708 | { 709 | left_top = QPointF(m_center.x() + m_edge.x() - m_edge.y(), (-1) * m_edge.y()); 710 | left_bottom = QPointF(m_center.x() + m_edge.x() - m_edge.y(), m_edge.y()); 711 | right_top = QPointF(m_center.x() - m_edge.x() + m_edge.y(), (-1) * m_edge.y()); 712 | right_bottom = QPointF(m_center.x() - m_edge.x() + m_edge.y(), m_edge.y()); 713 | } 714 | else if ( m_edge.x() >= 0 && m_edge.y() >=0 ) 715 | { 716 | left_top = QPointF(m_center.x() - m_edge.x() - m_edge.y(), (-1) * m_edge.y()); 717 | left_bottom = QPointF(m_center.x() - m_edge.x() - m_edge.y(), m_edge.y()); 718 | right_top = QPointF(m_center.x() + m_edge.x() + m_edge.y(), (-1) * m_edge.y()); 719 | right_bottom = QPointF(m_center.x() + m_edge.x() + m_edge.y(), m_edge.y()); 720 | } 721 | 722 | int radius = abs(m_edge.y()); 723 | QPointF deltax(radius, 0); 724 | QPointF deltay(0, radius); 725 | 726 | painter->drawLine(left_top + deltax, right_top - deltax); 727 | painter->drawLine(left_bottom + deltax, right_bottom - deltax); 728 | painter->drawLine(left_top + deltay, left_bottom - deltay); 729 | painter->drawLine(right_top + deltay, right_bottom - deltay); 730 | 731 | painter->drawArc(QRectF(left_top, QSizeF(radius*2, radius*2)), -180 * 16, -90 * 16); 732 | painter->drawArc(QRectF(left_bottom-deltay*2, QSizeF(radius*2, radius*2)), -90 * 16, -90 * 16); 733 | painter->drawArc(QRectF(right_top-deltax*2, QSizeF(radius*2, radius*2)), 0 * 16, 90 * 16); 734 | painter->drawArc(QRectF(right_bottom-deltax*2-deltay*2, QSizeF(radius*2, radius*2)), 0 * 16, -90 * 16); 735 | } 736 | 737 | //------------------------------------------------------------------------------ 738 | 739 | BRounded_Rectangle::BRounded_Rectangle(qreal x, qreal y, qreal width, qreal height, ItemType type) 740 | : BRectangle(x, y, width, height, type) 741 | { 742 | m_another_edge.setX( m_edge.x() ); 743 | m_another_edge.setY( (-1) * m_edge.y() ); 744 | 745 | BPointItem *point = new BPointItem(this, m_another_edge, BPointItem::Special); 746 | point->setParentItem(this); 747 | point->setCursor(Qt::SizeAllCursor); 748 | m_pointList.append(point); 749 | m_pointList.setRandColor(); 750 | 751 | updateRadius(); 752 | } 753 | 754 | void BRounded_Rectangle::updateRadius() 755 | { 756 | qreal dx = 0; 757 | qreal dy = 0; 758 | qreal absX = abs(m_edge.x()); 759 | qreal absY = abs(m_edge.y()); 760 | 761 | if ( m_another_edge.x() >= 0 && m_another_edge.y() < 0 ) 762 | { 763 | dx = absX - m_another_edge.x(); 764 | dy = absY + m_another_edge.y(); 765 | } 766 | else if ( m_another_edge.x() < 0 && m_another_edge.y() < 0 ) 767 | { 768 | dx = absX + m_another_edge.x(); 769 | dy = absY + m_another_edge.y(); 770 | } 771 | else if ( m_another_edge.x() < 0 && m_another_edge.y() >= 0 ) 772 | { 773 | dx = absX + m_another_edge.x(); 774 | dy = absY - m_another_edge.y(); 775 | } 776 | else if ( m_another_edge.x() >= 0 && m_another_edge.y() >= 0 ) 777 | { 778 | dx = absX - m_another_edge.x(); 779 | dy = absY - m_another_edge.y(); 780 | } 781 | 782 | m_radius = dx >= dy ? dx : dy; 783 | } 784 | 785 | void BRounded_Rectangle::updateAnotherEdge(QPointF p) 786 | { 787 | qreal retX = 0; 788 | qreal retY = 0; 789 | 790 | if ( p.x() == m_another_edge.x() ) { 791 | retX = m_edge.x(); 792 | retY = (-1) * m_edge.y() + m_radius; 793 | } else { 794 | retX = m_edge.x() - m_radius; 795 | retY = (-1) * m_edge.y(); 796 | } 797 | 798 | m_another_edge.setX(retX); 799 | m_another_edge.setY(retY); 800 | m_pointList.at(2)->setPoint(m_another_edge); 801 | } 802 | 803 | qreal BRounded_Rectangle::getRadius() 804 | { 805 | return m_radius; 806 | } 807 | 808 | QPointF BRounded_Rectangle::getAnotherEdge() 809 | { 810 | return m_another_edge; 811 | } 812 | 813 | void BRounded_Rectangle::setAnotherEdge(QPointF p) 814 | { 815 | m_another_edge = p; 816 | } 817 | 818 | void BRounded_Rectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 819 | { 820 | Q_UNUSED(option); 821 | Q_UNUSED(widget); 822 | painter->setPen(this->pen()); 823 | painter->setBrush(this->brush()); 824 | 825 | QRectF ret(m_center.x() - m_edge.x(), m_center.y() - m_edge.y(), m_edge.x() * 2, m_edge.y() * 2); 826 | painter->drawRoundedRect(ret, m_radius, m_radius); 827 | } 828 | 829 | void BRounded_Rectangle::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) 830 | { 831 | if ( !this->isSelected() ) 832 | return; 833 | 834 | QMenu* menu = new QMenu(); 835 | menu->setStyleSheet("QMenu { background-color:rgb(89,87,87); border: 5px solid rgb(235,110,36); }"); 836 | 837 | QSpinBox* width_spinBox = new QSpinBox(menu); 838 | width_spinBox->setStyleSheet("QSpinBox{ width:120px; height:30px; font-size:16px; font-weight:bold; }"); 839 | width_spinBox->setRange(0, 1000); 840 | width_spinBox->setPrefix("w: "); 841 | width_spinBox->setSuffix(" mm"); 842 | width_spinBox->setSingleStep(1); 843 | width_spinBox->setValue(2 * abs(m_edge.x())); 844 | connect(width_spinBox, static_cast(&QSpinBox::valueChanged), [=](int v){ 845 | m_another_edge.setX(m_another_edge.x() + v/2 - m_edge.x()); 846 | m_edge.setX(v/2); 847 | 848 | m_pointList.at(0)->setPoint(m_edge); 849 | m_pointList.at(2)->setPoint(m_another_edge); 850 | this->hide(); 851 | this->update(); 852 | this->show(); 853 | }); 854 | 855 | QSpinBox* height__spinBox = new QSpinBox(menu); 856 | height__spinBox->setStyleSheet("QSpinBox{ width:120px; height:30px; font-size:16px; font-weight:bold; }"); 857 | height__spinBox->setRange(0, 1000); 858 | height__spinBox->setPrefix("h: "); 859 | height__spinBox->setSuffix(" mm"); 860 | height__spinBox->setSingleStep(1); 861 | height__spinBox->setValue(2 * abs(m_edge.y())); 862 | connect(height__spinBox, static_cast(&QSpinBox::valueChanged), [=](int v){ 863 | m_another_edge.setY(m_another_edge.y() - v/2 + m_edge.y()); 864 | m_edge.setY(v/2); 865 | 866 | m_pointList.at(0)->setPoint(m_edge); 867 | m_pointList.at(2)->setPoint(m_another_edge); 868 | this->hide(); 869 | this->update(); 870 | this->show(); 871 | }); 872 | 873 | QSpinBox* radius__spinBox = new QSpinBox(menu); 874 | radius__spinBox->setStyleSheet("QSpinBox{ width:120px; height:30px; font-size:16px; font-weight:bold; }"); 875 | radius__spinBox->setRange(0, 1000); 876 | radius__spinBox->setPrefix("r: "); 877 | radius__spinBox->setSuffix(" mm"); 878 | radius__spinBox->setSingleStep(1); 879 | radius__spinBox->setValue(m_radius); 880 | connect(radius__spinBox, static_cast(&QSpinBox::valueChanged), [=](int v){ 881 | if (m_another_edge.x() >= abs(m_another_edge.y())) { 882 | m_radius = v <= m_edge.y() ? v : m_edge.y(); 883 | m_another_edge.setY((m_edge.y() - m_radius) * (-1)); 884 | } else { 885 | m_radius = v <= m_edge.x() ? v : m_edge.x(); 886 | m_another_edge.setX(m_edge.x() - m_radius); 887 | } 888 | 889 | m_pointList.at(2)->setPoint(m_another_edge); 890 | this->hide(); 891 | this->update(); 892 | this->show(); 893 | }); 894 | 895 | QWidgetAction* width_widgetAction = new QWidgetAction(menu); 896 | width_widgetAction->setDefaultWidget(width_spinBox); 897 | menu->addAction(width_widgetAction); 898 | 899 | QWidgetAction* height_widgetAction = new QWidgetAction(menu); 900 | height_widgetAction->setDefaultWidget(height__spinBox); 901 | menu->addAction(height_widgetAction); 902 | 903 | QWidgetAction* radius_widgetAction = new QWidgetAction(menu); 904 | radius_widgetAction->setDefaultWidget(radius__spinBox); 905 | menu->addAction(radius_widgetAction); 906 | 907 | menu->exec(QCursor::pos()); 908 | delete menu; 909 | 910 | QGraphicsItem::contextMenuEvent(event); 911 | } 912 | 913 | //------------------------------------------------------------------------------ 914 | -------------------------------------------------------------------------------- /bqgraphicsitem.h: -------------------------------------------------------------------------------- 1 | #ifndef BQGRAPHICSITEM_H 2 | #define BQGRAPHICSITEM_H 3 | 4 | #include 5 | #include "bpointitem.h" 6 | 7 | #define PI 3.1415926 8 | 9 | // 自定义图元 - 基础类 10 | class BGraphicsItem : public QObject, public QAbstractGraphicsShapeItem 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | enum ItemType { 16 | Circle = 0, // 圆 17 | Ellipse, // 椭圆 18 | Concentric_Circle, // 同心圆 19 | Pie, // 饼 20 | Chord, // 和弦 21 | Rectangle, // 矩形 22 | Square, // 正方形 23 | Polygon, // 多边形 24 | Round_End_Rectangle,// 圆端矩形 25 | Rounded_Rectangle // 圆角矩形 26 | }; 27 | 28 | QPointF getCenter() { return m_center; } 29 | void setCenter(QPointF p) { m_center = p; } 30 | 31 | QPointF getEdge() { return m_edge; } 32 | void setEdge(QPointF p) { m_edge = p; } 33 | 34 | ItemType getType() { return m_type; } 35 | 36 | protected: 37 | BGraphicsItem(QPointF center, QPointF edge, ItemType type); 38 | 39 | virtual void focusInEvent(QFocusEvent *event) override; 40 | virtual void focusOutEvent(QFocusEvent *event) override; 41 | 42 | public: 43 | QPointF m_center; 44 | QPointF m_edge; 45 | ItemType m_type; 46 | BPointItemList m_pointList; 47 | 48 | QPen m_pen_isSelected; 49 | QPen m_pen_noSelected; 50 | }; 51 | 52 | //------------------------------------------------------------------------------ 53 | 54 | // 椭圆 55 | class BEllipse : public BGraphicsItem 56 | { 57 | Q_OBJECT 58 | 59 | public: 60 | BEllipse(qreal x, qreal y, qreal width, qreal height, ItemType type); 61 | 62 | protected: 63 | virtual QRectF boundingRect() const override; 64 | 65 | virtual void paint(QPainter *painter, 66 | const QStyleOptionGraphicsItem *option, 67 | QWidget *widget) override; 68 | 69 | virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; 70 | }; 71 | 72 | //------------------------------------------------------------------------------ 73 | 74 | // 圆 75 | class BCircle : public BEllipse 76 | { 77 | public: 78 | BCircle(qreal x, qreal y, qreal radius, ItemType type); 79 | 80 | void updateRadius(); 81 | 82 | protected: 83 | virtual QRectF boundingRect() const override; 84 | 85 | virtual void paint(QPainter *painter, 86 | const QStyleOptionGraphicsItem *option, 87 | QWidget *widget) override; 88 | 89 | virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; 90 | 91 | public: 92 | qreal m_radius; 93 | }; 94 | 95 | //------------------------------------------------------------------------------ 96 | 97 | // 同心圆 98 | class BConcentricCircle : public BCircle 99 | { 100 | public: 101 | BConcentricCircle(qreal x, qreal y, qreal radius1, qreal radius2, ItemType type); 102 | 103 | void updateOtherRadius(); 104 | void setAnotherEdge(QPointF p); 105 | 106 | protected: 107 | virtual QRectF boundingRect() const override; 108 | 109 | virtual void paint(QPainter *painter, 110 | const QStyleOptionGraphicsItem *option, 111 | QWidget *widget) override; 112 | 113 | virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; 114 | 115 | public: 116 | QPointF m_another_edge; 117 | qreal m_another_radius; 118 | }; 119 | 120 | //------------------------------------------------------------------------------ 121 | 122 | // 饼 123 | class BPie : public BCircle 124 | { 125 | public: 126 | BPie(qreal x, qreal y, qreal radius, qreal angle, ItemType type); 127 | 128 | void updateAngle(); 129 | 130 | protected: 131 | virtual void paint(QPainter *painter, 132 | const QStyleOptionGraphicsItem *option, 133 | QWidget *widget) override; 134 | 135 | public: 136 | qreal m_angle; 137 | }; 138 | 139 | //------------------------------------------------------------------------------ 140 | 141 | // 和弦 142 | class BChord : public BPie 143 | { 144 | public: 145 | BChord(qreal x, qreal y, qreal radius, qreal angle, ItemType type); 146 | 147 | void updateEndAngle(); 148 | 149 | protected: 150 | virtual void paint(QPainter *painter, 151 | const QStyleOptionGraphicsItem *option, 152 | QWidget *widget) override; 153 | 154 | public: 155 | qreal m_end_angle; 156 | }; 157 | 158 | //------------------------------------------------------------------------------ 159 | 160 | // 矩形 161 | class BRectangle : public BGraphicsItem 162 | { 163 | public: 164 | BRectangle(qreal x, qreal y, qreal width, qreal height, ItemType type); 165 | 166 | protected: 167 | virtual QRectF boundingRect() const override; 168 | 169 | virtual void paint(QPainter *painter, 170 | const QStyleOptionGraphicsItem *option, 171 | QWidget *widget) override; 172 | 173 | virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; 174 | }; 175 | 176 | //------------------------------------------------------------------------------ 177 | 178 | // 正方形 179 | class BSquare : public BRectangle 180 | { 181 | public: 182 | BSquare(qreal x, qreal y, qreal width, ItemType type); 183 | 184 | protected: 185 | virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; 186 | }; 187 | 188 | //------------------------------------------------------------------------------ 189 | 190 | // 多边形 191 | class BPolygon : public BGraphicsItem 192 | { 193 | Q_OBJECT 194 | 195 | public: 196 | BPolygon(ItemType type); 197 | 198 | QPointF getCentroid(QList list); 199 | void getMaxLength(); 200 | void updatePolygon(QPointF origin, QPointF end); 201 | 202 | public slots: 203 | void pushPoint(QPointF p, QList list, bool isCenter); 204 | 205 | protected: 206 | virtual QRectF boundingRect() const override; 207 | 208 | virtual void paint(QPainter *painter, 209 | const QStyleOptionGraphicsItem *option, 210 | QWidget *widget) override; 211 | 212 | public: 213 | qreal m_radius; 214 | bool is_create_finished; 215 | }; 216 | 217 | //------------------------------------------------------------------------------ 218 | 219 | // 圆端矩形 220 | class BRound_End_Rectangle : public BRectangle 221 | { 222 | public: 223 | BRound_End_Rectangle(qreal x, qreal y, qreal width, qreal height, ItemType type); 224 | 225 | protected: 226 | virtual QRectF boundingRect() const override; 227 | 228 | virtual void paint(QPainter *painter, 229 | const QStyleOptionGraphicsItem *option, 230 | QWidget *widget) override; 231 | }; 232 | 233 | //------------------------------------------------------------------------------ 234 | 235 | // 圆角矩形 236 | class BRounded_Rectangle : public BRectangle 237 | { 238 | public: 239 | BRounded_Rectangle(qreal x, qreal y, qreal width, qreal height, ItemType type); 240 | 241 | void updateRadius(); 242 | void updateAnotherEdge(QPointF p); 243 | qreal getRadius(); 244 | QPointF getAnotherEdge(); 245 | void setAnotherEdge(QPointF p); 246 | 247 | protected: 248 | virtual void paint(QPainter *painter, 249 | const QStyleOptionGraphicsItem *option, 250 | QWidget *widget) override; 251 | 252 | virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; 253 | 254 | public: 255 | QPointF m_another_edge; 256 | qreal m_radius; 257 | }; 258 | 259 | //------------------------------------------------------------------------------ 260 | 261 | #endif // BQGRAPHICSITEM_H 262 | -------------------------------------------------------------------------------- /bqgraphicsscene.cpp: -------------------------------------------------------------------------------- 1 | #include "bqgraphicsscene.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | BQGraphicsScene::BQGraphicsScene(QObject *parent) : QGraphicsScene(parent) 8 | { 9 | is_creating_BPolygon = false; 10 | } 11 | 12 | void BQGraphicsScene::startCreate() 13 | { 14 | is_creating_BPolygon = true; 15 | m_list.clear(); 16 | } 17 | 18 | void BQGraphicsScene::saveItemToConfig() 19 | { 20 | QString fileName = QDir::currentPath() + "/item.ini"; 21 | if ( QFile::exists(fileName) ) { 22 | QFile(fileName).remove(); 23 | } 24 | 25 | QSettings setting(fileName, QSettings::IniFormat); 26 | 27 | QList list = this->items(); 28 | 29 | setting.beginWriteArray("itemList"); 30 | for ( int i = 0; i < list.size(); ++i ) 31 | { 32 | setting.setArrayIndex(i); 33 | 34 | BGraphicsItem *item = static_cast(list[i]); 35 | BGraphicsItem::ItemType type = item->getType(); 36 | setting.setValue("type", (int)type); 37 | setting.setValue("x", item->x()); 38 | setting.setValue("y", item->y()); 39 | 40 | switch (type) 41 | { 42 | case BGraphicsItem::ItemType::Circle: { 43 | BCircle *circle = static_cast(item); 44 | setting.setValue("radius", circle->m_radius); 45 | } break; 46 | case BGraphicsItem::ItemType::Ellipse: { 47 | BEllipse *ellipse = static_cast(item); 48 | setting.setValue("edgeX", ellipse->getEdge().x()); 49 | setting.setValue("edgeY", ellipse->getEdge().y()); 50 | } break; 51 | case BGraphicsItem::ItemType::Concentric_Circle: { 52 | BConcentricCircle *conCircle = static_cast(item); 53 | setting.setValue("radius", conCircle->m_radius); 54 | setting.setValue("radius2", conCircle->m_another_radius); 55 | } break; 56 | case BGraphicsItem::ItemType::Pie: { 57 | BPie *pie = static_cast(item); 58 | setting.setValue("radius", pie->m_radius); 59 | setting.setValue("angle", pie->m_angle); 60 | } break; 61 | case BGraphicsItem::ItemType::Chord: { 62 | BChord *chord = static_cast(item); 63 | setting.setValue("radius", chord->m_radius); 64 | setting.setValue("angle", chord->m_angle); 65 | } break; 66 | case BGraphicsItem::ItemType::Rectangle: { 67 | BRectangle *rectangle = static_cast(item); 68 | setting.setValue("edgeX", rectangle->getEdge().x()); 69 | setting.setValue("edgeY", rectangle->getEdge().y()); 70 | } break; 71 | case BGraphicsItem::ItemType::Square: { 72 | BSquare *square = static_cast(item); 73 | setting.setValue("edgeX", square->getEdge().x()); 74 | } break; 75 | case BGraphicsItem::ItemType::Polygon: { 76 | BPolygon *polygon = static_cast(item); 77 | BPointItemList list = polygon->m_pointList; 78 | setting.beginWriteArray("polygon"); 79 | for ( int j = 0; j < list.size() - 1; j++ ) 80 | { 81 | setting.setArrayIndex(j); 82 | setting.setValue("edge", list.at(j)->m_point); 83 | } 84 | setting.endArray(); 85 | } break; 86 | case BGraphicsItem::ItemType::Round_End_Rectangle: { 87 | BRound_End_Rectangle *round_End_Rectangle = static_cast(item); 88 | setting.setValue("edgeX", round_End_Rectangle->getEdge().x()); 89 | setting.setValue("edgeY", round_End_Rectangle->getEdge().y()); 90 | } break; 91 | case BGraphicsItem::ItemType::Rounded_Rectangle: { 92 | BRounded_Rectangle *rounded_Rectangle = static_cast(item); 93 | setting.setValue("edgeX", rounded_Rectangle->getEdge().x()); 94 | setting.setValue("edgeY", rounded_Rectangle->getEdge().y()); 95 | setting.setValue("radius", rounded_Rectangle->m_radius); 96 | } break; 97 | default: break; 98 | } 99 | } 100 | setting.endArray(); 101 | } 102 | 103 | void BQGraphicsScene::loadItemToScene() 104 | { 105 | this->clear(); 106 | 107 | QString fileName = QDir::currentPath() + "/item.ini"; 108 | QSettings setting(fileName, QSettings::IniFormat); 109 | 110 | int size = setting.beginReadArray("itemList"); 111 | for ( int i = 0; i < size; ++i ) 112 | { 113 | setting.setArrayIndex(i); 114 | 115 | BGraphicsItem::ItemType type = (BGraphicsItem::ItemType)setting.value("type").toInt(); 116 | 117 | switch (type) 118 | { 119 | case BGraphicsItem::ItemType::Circle: { 120 | qreal radius = setting.value("radius").toDouble(); 121 | BCircle *m_circle = new BCircle(0, 0, radius, BGraphicsItem::ItemType::Circle); 122 | m_circle->setX(setting.value("x").toDouble()); 123 | m_circle->setY(setting.value("y").toDouble()); 124 | addItem(m_circle); 125 | } break; 126 | case BGraphicsItem::ItemType::Ellipse: { 127 | qreal edgeX = setting.value("edgeX").toDouble(); 128 | qreal edgeY = setting.value("edgeY").toDouble(); 129 | BEllipse *m_ellipse = new BEllipse(0, 0, edgeX*2, edgeY*2, BGraphicsItem::ItemType::Ellipse); 130 | m_ellipse->setX(setting.value("x").toDouble()); 131 | m_ellipse->setY(setting.value("y").toDouble()); 132 | addItem(m_ellipse); 133 | } break; 134 | case BGraphicsItem::ItemType::Concentric_Circle: { 135 | qreal radius = setting.value("radius").toDouble(); 136 | qreal radius2 = setting.value("radius2").toDouble(); 137 | BConcentricCircle *m_conCircle = new BConcentricCircle(0, 0, radius, radius2, BGraphicsItem::ItemType::Concentric_Circle); 138 | m_conCircle->setX(setting.value("x").toDouble()); 139 | m_conCircle->setY(setting.value("y").toDouble()); 140 | addItem(m_conCircle); 141 | } break; 142 | case BGraphicsItem::ItemType::Pie: { 143 | qreal radius = setting.value("radius").toDouble(); 144 | qreal angle = setting.value("angle").toDouble(); 145 | BPie *m_pie = new BPie(0, 0, radius, angle, BGraphicsItem::ItemType::Pie); 146 | m_pie->setX(setting.value("x").toDouble()); 147 | m_pie->setY(setting.value("y").toDouble()); 148 | addItem(m_pie); 149 | } break; 150 | case BGraphicsItem::ItemType::Chord: { 151 | qreal radius = setting.value("radius").toDouble(); 152 | qreal angle = setting.value("angle").toDouble(); 153 | BChord *m_chord = new BChord(0, 0, radius, angle, BGraphicsItem::ItemType::Chord); 154 | m_chord->setX(setting.value("x").toDouble()); 155 | m_chord->setY(setting.value("y").toDouble()); 156 | addItem(m_chord); 157 | } break; 158 | case BGraphicsItem::ItemType::Rectangle: { 159 | qreal edgeX = setting.value("edgeX").toDouble(); 160 | qreal edgeY = setting.value("edgeY").toDouble(); 161 | BRectangle *m_rectangle = new BRectangle(0, 0, edgeX*2, edgeY*2, BGraphicsItem::ItemType::Rectangle); 162 | m_rectangle->setX(setting.value("x").toDouble()); 163 | m_rectangle->setY(setting.value("y").toDouble()); 164 | addItem(m_rectangle); 165 | } break; 166 | case BGraphicsItem::ItemType::Square: { 167 | qreal edgeX = setting.value("edgeX").toDouble(); 168 | BSquare *m_square = new BSquare(0, 0, edgeX*2, BGraphicsItem::ItemType::Square); 169 | m_square->setX(setting.value("x").toDouble()); 170 | m_square->setY(setting.value("y").toDouble()); 171 | addItem(m_square); 172 | } break; 173 | case BGraphicsItem::ItemType::Polygon: { 174 | startCreate(); 175 | BPolygon *m_polygon = new BPolygon(BGraphicsItem::ItemType::Polygon); 176 | addItem(m_polygon); 177 | 178 | int count = setting.beginReadArray("polygon"); 179 | QList list; 180 | for ( int j = 0; j < count; ++j ) 181 | { 182 | setting.setArrayIndex(j); 183 | QPointF edge = setting.value("edge").toPointF(); 184 | list.append(edge); 185 | m_polygon->pushPoint(edge, list, false); 186 | } 187 | setting.endArray(); 188 | 189 | m_polygon->setX(setting.value("x").toDouble()); 190 | m_polygon->setY(setting.value("y").toDouble()); 191 | m_polygon->pushPoint(QPointF(0,0), list, true); 192 | is_creating_BPolygon = false; 193 | } break; 194 | case BGraphicsItem::ItemType::Round_End_Rectangle: { 195 | qreal edgeX = setting.value("edgeX").toDouble(); 196 | qreal edgeY = setting.value("edgeY").toDouble(); 197 | BRound_End_Rectangle *m_round_end_Rectangle = new BRound_End_Rectangle(0, 0, edgeX*2, edgeY*2, 198 | BGraphicsItem::ItemType::Round_End_Rectangle); 199 | m_round_end_Rectangle->setX(setting.value("x").toDouble()); 200 | m_round_end_Rectangle->setY(setting.value("y").toDouble()); 201 | addItem(m_round_end_Rectangle); 202 | } break; 203 | case BGraphicsItem::ItemType::Rounded_Rectangle: { 204 | qreal edgeX = setting.value("edgeX").toDouble(); 205 | qreal edgeY = setting.value("edgeY").toDouble(); 206 | qreal radius = setting.value("radius").toDouble(); 207 | BRounded_Rectangle *m_rounded_Rectangle = new BRounded_Rectangle(0, 0, edgeX*2, edgeY*2, 208 | BGraphicsItem::ItemType::Rounded_Rectangle); 209 | m_rounded_Rectangle->m_radius = radius; 210 | m_rounded_Rectangle->setX(setting.value("x").toDouble()); 211 | m_rounded_Rectangle->setY(setting.value("y").toDouble()); 212 | addItem(m_rounded_Rectangle); 213 | } break; 214 | default: break; 215 | } 216 | } 217 | setting.endArray(); 218 | } 219 | 220 | void BQGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event) 221 | { 222 | if (is_creating_BPolygon) { 223 | QPointF p(event->scenePos().x(), event->scenePos().y()); 224 | 225 | switch ( event->buttons() ) 226 | { 227 | case Qt::LeftButton: { 228 | m_list.push_back(p); 229 | emit updatePoint(p, m_list, false); 230 | } break; 231 | case Qt::RightButton: { 232 | if (m_list.size() >= 3) { 233 | emit updatePoint(p, m_list, true); 234 | emit createFinished(); 235 | is_creating_BPolygon = false; 236 | m_list.clear(); 237 | } 238 | } break; 239 | default: break; 240 | } 241 | } else { 242 | QGraphicsScene::mousePressEvent(event); 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /bqgraphicsscene.h: -------------------------------------------------------------------------------- 1 | #ifndef BQGRAPHICSSCENE_H 2 | #define BQGRAPHICSSCENE_H 3 | 4 | #include 5 | #include "bpointitem.h" 6 | #include "bqgraphicsitem.h" 7 | 8 | class BQGraphicsScene : public QGraphicsScene 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | BQGraphicsScene(QObject *parent = nullptr); 14 | 15 | void startCreate(); 16 | void saveItemToConfig(); 17 | void loadItemToScene(); 18 | 19 | protected: 20 | virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); 21 | 22 | signals: 23 | void updatePoint(QPointF p, QList list, bool isCenter); 24 | void createFinished(); 25 | 26 | protected: 27 | QList m_list; 28 | bool is_creating_BPolygon; 29 | }; 30 | 31 | #endif // BQGRAPHICSSCENE_H 32 | -------------------------------------------------------------------------------- /bqgraphicsview.cpp: -------------------------------------------------------------------------------- 1 | #include "bqgraphicsview.h" 2 | 3 | BQGraphicsView::BQGraphicsView(QWidget *parent) : QGraphicsView(parent) 4 | { 5 | // 隐藏水平/竖直滚动条 6 | setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 7 | setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 8 | 9 | // 设置场景范围 10 | setSceneRect(INT_MIN / 2, INT_MIN / 2, INT_MAX, INT_MAX); 11 | 12 | // 反锯齿 13 | setRenderHints(QPainter::Antialiasing); 14 | } 15 | 16 | void BQGraphicsView::mousePressEvent(QMouseEvent *event) 17 | { 18 | QGraphicsView::mousePressEvent(event); 19 | } 20 | -------------------------------------------------------------------------------- /bqgraphicsview.h: -------------------------------------------------------------------------------- 1 | #ifndef BQGRAPHICSVIEW_H 2 | #define BQGRAPHICSVIEW_H 3 | 4 | #include 5 | #include 6 | 7 | class BQGraphicsView : public QGraphicsView 8 | { 9 | public: 10 | BQGraphicsView(QWidget *parent = nullptr); 11 | 12 | protected: 13 | virtual void mousePressEvent(QMouseEvent *event) override; 14 | }; 15 | 16 | #endif // BQGRAPHICSVIEW_H 17 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | QApplication a(argc, argv); 8 | MainWindow w; 9 | w.show(); 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | 4 | MainWindow::MainWindow(QWidget *parent) 5 | : QMainWindow(parent) 6 | , ui(new Ui::MainWindow) 7 | { 8 | ui->setupUi(this); 9 | setWindowTitle(QStringLiteral("自定义图形")); 10 | setMaximumSize(1024, 768); 11 | setMinimumSize(1027, 768); 12 | 13 | m_scene.setBackgroundBrush(Qt::gray); 14 | ui->graphicsView->setScene(&m_scene); 15 | } 16 | 17 | MainWindow::~MainWindow() 18 | { 19 | delete ui; 20 | } 21 | 22 | void MainWindow::on_circleBtn_clicked() 23 | { 24 | BCircle *m_circle = new BCircle(0, 0, 50, BGraphicsItem::ItemType::Circle); 25 | m_scene.addItem(m_circle); 26 | } 27 | 28 | void MainWindow::on_ellipseBtn_clicked() 29 | { 30 | BEllipse *m_ellipse = new BEllipse(0, 0, 120, 80, BGraphicsItem::ItemType::Ellipse); 31 | m_scene.addItem(m_ellipse); 32 | } 33 | 34 | void MainWindow::on_conCircleBtn_clicked() 35 | { 36 | BConcentricCircle *m_conCircle = new BConcentricCircle(0, 0, 50, 80, BGraphicsItem::ItemType::Concentric_Circle); 37 | m_scene.addItem(m_conCircle); 38 | } 39 | 40 | void MainWindow::on_pieBtn_clicked() 41 | { 42 | BPie *m_pie = new BPie(0, 0, 80, 30, BGraphicsItem::ItemType::Pie); 43 | m_scene.addItem(m_pie); 44 | } 45 | 46 | void MainWindow::on_chordBtn_clicked() 47 | { 48 | BChord *m_chord = new BChord(0, 0, 80, 30, BGraphicsItem::ItemType::Chord); 49 | m_scene.addItem(m_chord); 50 | } 51 | 52 | void MainWindow::on_squareBtn_clicked() 53 | { 54 | BSquare *m_square = new BSquare(0, 0, 60, BGraphicsItem::ItemType::Square); 55 | m_scene.addItem(m_square); 56 | } 57 | 58 | void MainWindow::on_rectangleBtn_clicked() 59 | { 60 | BRectangle *m_rectangle = new BRectangle(0, 0, 80, 60, BGraphicsItem::ItemType::Rectangle); 61 | m_scene.addItem(m_rectangle); 62 | } 63 | 64 | void MainWindow::on_polygonBtn_clicked() 65 | { 66 | m_scene.startCreate(); 67 | setBtnEnabled(false); 68 | BPolygon *m_polygon = new BPolygon(BGraphicsItem::ItemType::Polygon); 69 | m_scene.addItem(m_polygon); 70 | 71 | connect(&m_scene, SIGNAL(updatePoint(QPointF, QList, bool)), m_polygon, SLOT(pushPoint(QPointF, QList, bool))); 72 | connect(&m_scene, &BQGraphicsScene::createFinished, [=](){ setBtnEnabled(true); }); 73 | } 74 | 75 | void MainWindow::on_rnRecBtn_clicked() 76 | { 77 | BRound_End_Rectangle *m_round_end_Rectangle = new BRound_End_Rectangle(0, 0, 80, 60, BGraphicsItem::ItemType::Round_End_Rectangle); 78 | m_scene.addItem(m_round_end_Rectangle); 79 | } 80 | 81 | void MainWindow::on_roundRecBtn_clicked() 82 | { 83 | BRounded_Rectangle *m_rounded_Rectangle = new BRounded_Rectangle(0, 0, 80, 60, BGraphicsItem::ItemType::Rounded_Rectangle); 84 | m_scene.addItem(m_rounded_Rectangle); 85 | } 86 | 87 | void MainWindow::on_clearBtn_clicked() 88 | { 89 | m_scene.clear(); 90 | } 91 | 92 | void MainWindow::on_saveBtn_clicked() 93 | { 94 | m_scene.saveItemToConfig(); 95 | } 96 | 97 | void MainWindow::on_loadBtn_clicked() 98 | { 99 | m_scene.loadItemToScene(); 100 | } 101 | 102 | void MainWindow::setBtnEnabled(bool enable) 103 | { 104 | ui->circleBtn->setEnabled(enable); 105 | ui->ellipseBtn->setEnabled(enable); 106 | ui->conCircleBtn->setEnabled(enable); 107 | ui->pieBtn->setEnabled(enable); 108 | ui->chordBtn->setEnabled(enable); 109 | ui->squareBtn->setEnabled(enable); 110 | ui->rectangleBtn->setEnabled(enable); 111 | ui->roundRecBtn->setEnabled(enable); 112 | ui->rnRecBtn->setEnabled(enable); 113 | ui->clearBtn->setEnabled(enable); 114 | ui->saveBtn->setEnabled(enable); 115 | ui->loadBtn->setEnabled(enable); 116 | } 117 | -------------------------------------------------------------------------------- /mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include "bqgraphicsitem.h" 6 | #include "bqgraphicsscene.h" 7 | 8 | QT_BEGIN_NAMESPACE 9 | namespace Ui { class MainWindow; } 10 | QT_END_NAMESPACE 11 | 12 | class MainWindow : public QMainWindow 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | MainWindow(QWidget *parent = nullptr); 18 | ~MainWindow(); 19 | 20 | void setBtnEnabled(bool enable); 21 | 22 | private slots: 23 | void on_circleBtn_clicked(); 24 | 25 | void on_ellipseBtn_clicked(); 26 | 27 | void on_conCircleBtn_clicked(); 28 | 29 | void on_pieBtn_clicked(); 30 | 31 | void on_chordBtn_clicked(); 32 | 33 | void on_squareBtn_clicked(); 34 | 35 | void on_rectangleBtn_clicked(); 36 | 37 | void on_polygonBtn_clicked(); 38 | 39 | void on_rnRecBtn_clicked(); 40 | 41 | void on_roundRecBtn_clicked(); 42 | 43 | void on_clearBtn_clicked(); 44 | 45 | void on_saveBtn_clicked(); 46 | 47 | void on_loadBtn_clicked(); 48 | 49 | private: 50 | Ui::MainWindow *ui; 51 | 52 | BQGraphicsScene m_scene; 53 | }; 54 | #endif // MAINWINDOW_H 55 | -------------------------------------------------------------------------------- /mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1024 10 | 768 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | 18 | 19 | 20 | 20 21 | 20 22 | 91 23 | 731 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 椭圆 38 | 39 | 40 | 41 | 42 | 43 | 44 | 同心圆 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 和弦 59 | 60 | 61 | 62 | 63 | 64 | 65 | 正方形 66 | 67 | 68 | 69 | 70 | 71 | 72 | 矩形 73 | 74 | 75 | 76 | 77 | 78 | 79 | 多边形 80 | 81 | 82 | 83 | 84 | 85 | 86 | 圆端矩形 87 | 88 | 89 | 90 | 91 | 92 | 93 | 圆角矩形 94 | 95 | 96 | 97 | 98 | 99 | 100 | 清空 101 | 102 | 103 | 104 | 105 | 106 | 107 | 保存 108 | 109 | 110 | 111 | 112 | 113 | 114 | 加载 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 140 124 | 20 125 | 861 126 | 731 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | BQGraphicsView 135 | QGraphicsView 136 |
bqgraphicsview.h
137 |
138 |
139 | 140 | 141 |
142 | --------------------------------------------------------------------------------