├── .gitignore ├── LICENSE ├── README.md ├── XYDrawTool.pro ├── XYShape ├── xyarrowsgraphicsitem.cpp ├── xyarrowsgraphicsitem.h ├── xycanvasgraphicsitem.cpp ├── xycanvasgraphicsitem.h ├── xyellipsegraphicsitem.cpp ├── xyellipsegraphicsitem.h ├── xylinegraphicsitem.cpp ├── xylinegraphicsitem.h ├── xymovablegraphicsitem.cpp ├── xymovablegraphicsitem.h ├── xypathgraphicsitem.cpp ├── xypathgraphicsitem.h ├── xypixmapgraphicsitem.cpp ├── xypixmapgraphicsitem.h ├── xypolygongraphicsitem.cpp ├── xypolygongraphicsitem.h ├── xyrectgraphicsitem.cpp ├── xyrectgraphicsitem.h ├── xyshapegraphicsitem.cpp ├── xyshapegraphicsitem.h ├── xytextgraphicsitem.cpp └── xytextgraphicsitem.h ├── drawtool.ico ├── ico.rc ├── images ├── arrows.ico ├── backimage.jpg ├── cursor.ico ├── delete.ico ├── draw.ico ├── drawtool.ico ├── ellipse.ico ├── images.qrc ├── line.ico ├── open.ico ├── pixmap.ico ├── polygon.ico ├── rect.ico ├── rotation.ico ├── save.ico ├── settingpen.ico ├── stick.ico ├── text.ico ├── zoomdown.ico └── zoomup.ico ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── version.h ├── xygraphicsscene.cpp ├── xygraphicsscene.h ├── xygraphicsview.cpp ├── xygraphicsview.h ├── xymovablewidget.cpp ├── xymovablewidget.h ├── xypensettingwidget.cpp └── xypensettingwidget.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Draw-Tool 2 | 绘图工具/图片编辑 3 | -------------------------------------------------------------------------------- /XYDrawTool.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2017-11-30T13:53:47 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = XYDrawTool 12 | TEMPLATE = app 13 | 14 | INCLUDEPATH += XYShape 15 | 16 | SOURCES += main.cpp\ 17 | xygraphicsview.cpp \ 18 | xygraphicsscene.cpp \ 19 | XYShape/xycanvasgraphicsitem.cpp \ 20 | XYShape/xyellipsegraphicsitem.cpp \ 21 | XYShape/xypathgraphicsitem.cpp \ 22 | XYShape/xyrectgraphicsitem.cpp \ 23 | mainwindow.cpp \ 24 | XYShape/xylinegraphicsitem.cpp \ 25 | XYShape/xymovablegraphicsitem.cpp \ 26 | XYShape/xyshapegraphicsitem.cpp \ 27 | XYShape/xyarrowsgraphicsitem.cpp \ 28 | XYShape/xytextgraphicsitem.cpp \ 29 | xymovablewidget.cpp \ 30 | xypensettingwidget.cpp \ 31 | XYShape/xypixmapgraphicsitem.cpp \ 32 | XYShape/xypolygongraphicsitem.cpp 33 | 34 | HEADERS += \ 35 | xygraphicsview.h \ 36 | xygraphicsscene.h \ 37 | XYShape/xycanvasgraphicsitem.h \ 38 | XYShape/xyellipsegraphicsitem.h \ 39 | XYShape/xypathgraphicsitem.h \ 40 | XYShape/xyrectgraphicsitem.h \ 41 | mainwindow.h \ 42 | XYShape/xylinegraphicsitem.h \ 43 | XYShape/xymovablegraphicsitem.h \ 44 | XYShape/xyshapegraphicsitem.h \ 45 | XYShape/xyarrowsgraphicsitem.h \ 46 | XYShape/xytextgraphicsitem.h \ 47 | xymovablewidget.h \ 48 | xypensettingwidget.h \ 49 | XYShape/xypixmapgraphicsitem.h \ 50 | version.h \ 51 | XYShape/xypolygongraphicsitem.h 52 | 53 | RESOURCES += \ 54 | images/images.qrc 55 | 56 | RC_FILE = ico.rc 57 | -------------------------------------------------------------------------------- /XYShape/xyarrowsgraphicsitem.cpp: -------------------------------------------------------------------------------- 1 | #include "xyarrowsgraphicsitem.h" 2 | 3 | XYArrowsGraphicsItem::XYArrowsGraphicsItem(const QPointF &start, 4 | const QPointF &end, 5 | QGraphicsItem *parent) 6 | : XYMovableGraphicsItem(parent) 7 | { 8 | len = 16; 9 | startPos = start; 10 | endPos = end; 11 | } 12 | 13 | QRectF XYArrowsGraphicsItem::boundingRect() const 14 | { 15 | QPainterPath path = getArrowsPath(startPos, endPos, len); 16 | return path.controlPointRect(); 17 | } 18 | 19 | void XYArrowsGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w) 20 | { 21 | XYMovableGraphicsItem::paint(painter, option, w); 22 | QPainterPath path = getArrowsPath(startPos, endPos, len); 23 | painter->drawPath(path); 24 | } 25 | 26 | QPainterPath XYArrowsGraphicsItem::getArrowsPath(const QPointF &start, 27 | const QPointF &end, 28 | qreal len) const 29 | { 30 | QPainterPath path; 31 | path.moveTo(start); 32 | 33 | QLineF line1 = getVerticalLine(end, start, len * sqrt(3) / 2, len / 2); 34 | QLineF line2 = getVerticalLine(end, start, len * sqrt(3) / 2, len); 35 | 36 | path.lineTo(line1.p1()); 37 | path.lineTo(line2.p1()); 38 | path.lineTo(end); 39 | path.lineTo(line2.p2()); 40 | path.lineTo(line1.p2()); 41 | path.lineTo(start); 42 | 43 | return path; 44 | } 45 | -------------------------------------------------------------------------------- /XYShape/xyarrowsgraphicsitem.h: -------------------------------------------------------------------------------- 1 | #ifndef XYARROWSGRAPHICSITEM_H 2 | #define XYARROWSGRAPHICSITEM_H 3 | 4 | #include "xymovablegraphicsitem.h" 5 | 6 | class XYArrowsGraphicsItem : public XYMovableGraphicsItem 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit XYArrowsGraphicsItem(const QPointF &start = QPointF(), 11 | const QPointF &end = QPointF(), 12 | QGraphicsItem *parent = 0); 13 | 14 | QRectF boundingRect() const Q_DECL_OVERRIDE; 15 | void paint(QPainter *painter, 16 | const QStyleOptionGraphicsItem *option, 17 | QWidget *w) Q_DECL_OVERRIDE; 18 | 19 | private: 20 | QPainterPath getArrowsPath(const QPointF &start, 21 | const QPointF &end, 22 | qreal len) const; 23 | 24 | private: 25 | qreal len; 26 | 27 | friend class XYGraphicsScene; 28 | }; 29 | 30 | #endif // XYARROWSGRAPHICSITEM_H 31 | -------------------------------------------------------------------------------- /XYShape/xycanvasgraphicsitem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "xycanvasgraphicsitem.h" 5 | #include "xyrectgraphicsitem.h" 6 | #include "xypathgraphicsitem.h" 7 | #include "xyellipsegraphicsitem.h" 8 | 9 | 10 | XYCanvasGraphicsItem::XYCanvasGraphicsItem(const QPixmap &pixmap, QGraphicsItem *parent) 11 | : XYShapeGraphicsItem(parent), backImage(pixmap) 12 | { 13 | 14 | } 15 | 16 | void XYCanvasGraphicsItem::setPixmap(const QPixmap &pixmap) 17 | { 18 | backImage = pixmap; 19 | } 20 | 21 | QRectF XYCanvasGraphicsItem::boundingRect() const 22 | { 23 | return backImage.rect(); 24 | } 25 | 26 | void XYCanvasGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) 27 | { 28 | int x = (scene()->sceneRect().width() - backImage.width()) / 2; 29 | int y = (scene()->sceneRect().height() - backImage.height()) / 2; 30 | painter->drawPixmap(x, y, backImage); 31 | } 32 | 33 | int XYCanvasGraphicsItem::type() const 34 | { 35 | return XYCANVAS; 36 | } 37 | -------------------------------------------------------------------------------- /XYShape/xycanvasgraphicsitem.h: -------------------------------------------------------------------------------- 1 | #ifndef XYCANVASGRAPHICSITEM_H 2 | #define XYCANVASGRAPHICSITEM_H 3 | 4 | #include "xyshapegraphicsitem.h" 5 | 6 | class XYCanvasGraphicsItem : public XYShapeGraphicsItem 7 | { 8 | Q_OBJECT 9 | public: 10 | enum {XYCANVAS = XYSHAPE + 10}; 11 | explicit XYCanvasGraphicsItem(const QPixmap &pixmap = QPixmap(), QGraphicsItem *parent = 0); 12 | 13 | void setPixmap(const QPixmap &pixmap); 14 | QRectF boundingRect() const Q_DECL_OVERRIDE; 15 | void paint(QPainter *painter, 16 | const QStyleOptionGraphicsItem *option, 17 | QWidget *) Q_DECL_OVERRIDE; 18 | 19 | int type() const; 20 | 21 | private: 22 | QPixmap backImage; 23 | }; 24 | 25 | #endif // XYCANVASGRAPHICSITEM_H 26 | -------------------------------------------------------------------------------- /XYShape/xyellipsegraphicsitem.cpp: -------------------------------------------------------------------------------- 1 | #include "xyellipsegraphicsitem.h" 2 | 3 | XYEllipseGraphicsItem::XYEllipseGraphicsItem(const QRectF &rect, QGraphicsItem *parent) 4 | : XYMovableGraphicsItem(parent), moRect(rect) 5 | { 6 | 7 | } 8 | 9 | QRectF XYEllipseGraphicsItem::boundingRect() const 10 | { 11 | return moRect; 12 | } 13 | 14 | void XYEllipseGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w) 15 | { 16 | XYMovableGraphicsItem::paint(painter, option, w); 17 | painter->drawEllipse(moRect); 18 | } 19 | -------------------------------------------------------------------------------- /XYShape/xyellipsegraphicsitem.h: -------------------------------------------------------------------------------- 1 | #ifndef XYELLIPSEGRAPHICSITEM_H 2 | #define XYELLIPSEGRAPHICSITEM_H 3 | 4 | #include "xymovablegraphicsitem.h" 5 | 6 | class XYEllipseGraphicsItem : public XYMovableGraphicsItem 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit XYEllipseGraphicsItem(const QRectF &rect = QRectF(), QGraphicsItem *parent = 0); 11 | 12 | QRectF boundingRect() const Q_DECL_OVERRIDE; 13 | void paint(QPainter *painter, 14 | const QStyleOptionGraphicsItem *option, 15 | QWidget *w) Q_DECL_OVERRIDE; 16 | private: 17 | QRectF moRect; 18 | 19 | friend class XYGraphicsScene; 20 | }; 21 | 22 | #endif // XYELLIPSEGRAPHICSITEM_H 23 | -------------------------------------------------------------------------------- /XYShape/xylinegraphicsitem.cpp: -------------------------------------------------------------------------------- 1 | #include "xylinegraphicsitem.h" 2 | 3 | XYLineGraphicsItem::XYLineGraphicsItem(const QLineF &line, QGraphicsItem *parent) 4 | : XYMovableGraphicsItem(parent) 5 | { 6 | 7 | } 8 | 9 | QRectF XYLineGraphicsItem::boundingRect() const 10 | { 11 | const qreal x1 = moLine.p1().x(); 12 | const qreal x2 = moLine.p2().x(); 13 | const qreal y1 = moLine.p1().y(); 14 | const qreal y2 = moLine.p2().y(); 15 | qreal lx = qMin(x1, x2); 16 | qreal rx = qMax(x1, x2); 17 | qreal ty = qMin(y1, y2); 18 | qreal by = qMax(y1, y2); 19 | return QRectF(lx, ty, rx - lx, by - ty); 20 | } 21 | 22 | void XYLineGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w) 23 | { 24 | XYMovableGraphicsItem::paint(painter, option, w); 25 | painter->drawLine(moLine); 26 | } 27 | -------------------------------------------------------------------------------- /XYShape/xylinegraphicsitem.h: -------------------------------------------------------------------------------- 1 | #ifndef XYLINEGRAPHICSITEM_H 2 | #define XYLINEGRAPHICSITEM_H 3 | 4 | #include "xymovablegraphicsitem.h" 5 | 6 | class XYLineGraphicsItem : public XYMovableGraphicsItem 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit XYLineGraphicsItem(const QLineF &line = QLineF(), QGraphicsItem *parent = 0); 11 | 12 | QRectF boundingRect() const Q_DECL_OVERRIDE; 13 | void paint(QPainter *painter, 14 | const QStyleOptionGraphicsItem *option, 15 | QWidget *w) Q_DECL_OVERRIDE; 16 | private: 17 | QLineF moLine; 18 | 19 | friend class XYGraphicsScene; 20 | }; 21 | 22 | #endif // XYLINEGRAPHICSITEM_H 23 | -------------------------------------------------------------------------------- /XYShape/xymovablegraphicsitem.cpp: -------------------------------------------------------------------------------- 1 | #include "xymovablegraphicsitem.h" 2 | 3 | bool XYMovableGraphicsItem::acceptMouse = false; 4 | XYMovableGraphicsItem::XYMovableGraphicsItem(QGraphicsItem *parent) 5 | : XYShapeGraphicsItem(parent), selected(false) 6 | { 7 | meType = XYSHAPEMOVABLE; 8 | setAcceptHoverEvents(true); 9 | } 10 | 11 | void XYMovableGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w) 12 | { 13 | XYShapeGraphicsItem::paint(painter, option, w); 14 | if (selected) 15 | { 16 | QPen pen = painter->pen(); 17 | pen.setColor(QColor("red")); 18 | painter->setPen(pen); 19 | } 20 | } 21 | 22 | void XYMovableGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event) 23 | { 24 | if (!acceptMouse) 25 | { 26 | return QGraphicsItem::mousePressEvent(event); 27 | } 28 | if (isHoverArea(event->scenePos())) 29 | { 30 | event->accept(); 31 | } 32 | selected = true; 33 | } 34 | 35 | void XYMovableGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) 36 | { 37 | if (!acceptMouse) 38 | { 39 | return QGraphicsItem::mouseReleaseEvent(event); 40 | } 41 | if (isHoverArea(event->scenePos())) 42 | { 43 | event->accept(); 44 | } 45 | } 46 | 47 | void XYMovableGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) 48 | { 49 | if (!acceptMouse) 50 | { 51 | return QGraphicsItem::mouseMoveEvent(event); 52 | } 53 | if (isHoverArea(event->scenePos())) 54 | { 55 | event->accept(); 56 | setPos(pos() + event->scenePos() - event->lastScenePos()); 57 | } 58 | } 59 | 60 | bool XYMovableGraphicsItem::isHoverArea(const QPointF &pos) 61 | { 62 | return true; 63 | } 64 | 65 | bool XYMovableGraphicsItem::isValid() 66 | { 67 | int w = startPos.x() - endPos.x(); 68 | int h = startPos.y() - endPos.y(); 69 | if (w * w + h * h < 10*10) // 控制误差范围 70 | { 71 | return false; 72 | } 73 | return true; 74 | } 75 | 76 | int XYMovableGraphicsItem::type() const 77 | { 78 | return meType; 79 | } 80 | 81 | void XYMovableGraphicsItem::startCreateItem(const QPointF &pos) 82 | { 83 | startPos = pos; 84 | endPos = pos; 85 | } 86 | 87 | void XYMovableGraphicsItem::duringCreateItem(const QPointF &pos) 88 | { 89 | endPos = pos; 90 | } 91 | 92 | void XYMovableGraphicsItem::endCreateItem(const QPointF &pos) 93 | { 94 | endPos = pos; 95 | selected = true; 96 | creating = false; 97 | } 98 | -------------------------------------------------------------------------------- /XYShape/xymovablegraphicsitem.h: -------------------------------------------------------------------------------- 1 | #ifndef XYGRAPHICSMOVABLEITEM_H 2 | #define XYGRAPHICSMOVABLEITEM_H 3 | 4 | #include "xyshapegraphicsitem.h" 5 | 6 | class XYMovableGraphicsItem : public XYShapeGraphicsItem 7 | { 8 | Q_OBJECT 9 | public: 10 | enum XYTYPE { XYSHAPEMOVABLE = XYSHAPE + 1, XYTEXT }; 11 | explicit XYMovableGraphicsItem(QGraphicsItem *parent = 0); 12 | 13 | void paint(QPainter *painter, 14 | const QStyleOptionGraphicsItem *option, 15 | QWidget *w) Q_DECL_OVERRIDE; 16 | 17 | protected: 18 | void mousePressEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; 19 | void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; 20 | void mouseMoveEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; 21 | 22 | // 指示该区域是否是悬浮区域(子类可以重写) 23 | virtual bool isHoverArea(const QPointF &pos); 24 | virtual bool isValid(); 25 | virtual int type() const; 26 | 27 | virtual void startCreateItem(const QPointF &pos); 28 | virtual void duringCreateItem(const QPointF &pos); 29 | virtual void endCreateItem(const QPointF &pos); 30 | 31 | protected: 32 | QPointF startPos; 33 | QPointF endPos; 34 | XYTYPE meType; 35 | bool selected; 36 | static bool acceptMouse; 37 | 38 | friend class XYGraphicsScene; 39 | }; 40 | 41 | #endif // XYGRAPHICSMOVABLEITEM_H 42 | -------------------------------------------------------------------------------- /XYShape/xypathgraphicsitem.cpp: -------------------------------------------------------------------------------- 1 | #include "xypathgraphicsitem.h" 2 | 3 | XYPathGraphicsItem::XYPathGraphicsItem(const QPainterPath &path, QGraphicsItem *parent) 4 | : XYMovableGraphicsItem(parent), moPath(path) 5 | { 6 | 7 | } 8 | 9 | QRectF XYPathGraphicsItem::boundingRect() const 10 | { 11 | return moPath.controlPointRect(); 12 | } 13 | 14 | void XYPathGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w) 15 | { 16 | XYMovableGraphicsItem::paint(painter, option, w); 17 | painter->drawPath(moPath); 18 | } 19 | 20 | bool XYPathGraphicsItem::isValid() 21 | { 22 | int w = moPath.controlPointRect().size().width(); 23 | int h = moPath.controlPointRect().size().height(); 24 | if (w * w + h * h < 5*5) 25 | { 26 | return false; 27 | } 28 | return true; 29 | } 30 | -------------------------------------------------------------------------------- /XYShape/xypathgraphicsitem.h: -------------------------------------------------------------------------------- 1 | #ifndef XYGRAPHICSPATHITEM_H 2 | #define XYGRAPHICSPATHITEM_H 3 | 4 | #include "xymovablegraphicsitem.h" 5 | 6 | class XYPathGraphicsItem : public XYMovableGraphicsItem 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit XYPathGraphicsItem(const QPainterPath &path = QPainterPath(), QGraphicsItem *parent = 0); 11 | 12 | QRectF boundingRect() const Q_DECL_OVERRIDE; 13 | void paint(QPainter *painter, 14 | const QStyleOptionGraphicsItem *option, 15 | QWidget *w) Q_DECL_OVERRIDE; 16 | bool isValid(); 17 | 18 | private: 19 | QPainterPath moPath; 20 | 21 | friend class XYGraphicsScene; 22 | }; 23 | 24 | #endif // XYGRAPHICSPATHITEM_H 25 | -------------------------------------------------------------------------------- /XYShape/xypixmapgraphicsitem.cpp: -------------------------------------------------------------------------------- 1 | #include "xypixmapgraphicsitem.h" 2 | #include "xygraphicsscene.h" 3 | #include 4 | 5 | XYPixmapGraphicsItem::XYPixmapGraphicsItem(const QPixmap &pixmap, QGraphicsItem *parent) 6 | : QGraphicsPixmapItem(pixmap, parent), QObject() 7 | { 8 | setCacheMode(DeviceCoordinateCache); 9 | } 10 | 11 | void XYPixmapGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event) 12 | { 13 | event->accept(); 14 | } 15 | 16 | void XYPixmapGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) 17 | { 18 | event->accept(); 19 | } 20 | 21 | void XYPixmapGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) 22 | { 23 | event->accept(); 24 | setPos(pos() + event->scenePos() - event->lastScenePos()); 25 | } 26 | -------------------------------------------------------------------------------- /XYShape/xypixmapgraphicsitem.h: -------------------------------------------------------------------------------- 1 | #ifndef XYPIXMAPGRAPHICSITEM_H 2 | #define XYPIXMAPGRAPHICSITEM_H 3 | 4 | #include 5 | 6 | class XYPixmapGraphicsItem : public QObject, public QGraphicsPixmapItem 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit XYPixmapGraphicsItem(const QPixmap &pixmap = QPixmap(), 11 | QGraphicsItem *parent = 0); 12 | 13 | protected: 14 | void mousePressEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; 15 | void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; 16 | void mouseMoveEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; 17 | 18 | private: // 这个类单独实现paint函数在移动的时候会出现问题,目前不知道怎么实现,转而继承QT自身实现的 19 | friend class XYGraphicsScene; 20 | }; 21 | 22 | #endif // XYPIXMAPGRAPHICSITEM_H 23 | -------------------------------------------------------------------------------- /XYShape/xypolygongraphicsitem.cpp: -------------------------------------------------------------------------------- 1 | #include "xypolygongraphicsitem.h" 2 | 3 | XYPolygonGraphicsitem::XYPolygonGraphicsitem(QGraphicsItem *parent) 4 | : XYMovableGraphicsItem(parent) 5 | { 6 | 7 | } 8 | 9 | XYPolygonGraphicsitem::~XYPolygonGraphicsitem() 10 | { 11 | 12 | } 13 | 14 | QRectF XYPolygonGraphicsitem::boundingRect() const 15 | { 16 | QPainterPath path; 17 | path.moveTo(startPos); 18 | for (int i = 0; i < allPoints.size(); ++i) 19 | { 20 | path.lineTo(allPoints.at(i)); 21 | } 22 | path.lineTo(endPos); 23 | path.lineTo(startPos); 24 | return path.controlPointRect(); 25 | } 26 | 27 | void XYPolygonGraphicsitem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w) 28 | { 29 | XYMovableGraphicsItem::paint(painter, option, w); 30 | QPainterPath path; 31 | path.moveTo(startPos); 32 | for (int i = 0; i < allPoints.size(); ++i) 33 | { 34 | path.lineTo(allPoints.at(i)); 35 | } 36 | path.lineTo(endPos); 37 | path.lineTo(startPos); 38 | 39 | painter->drawPath(path); 40 | } 41 | -------------------------------------------------------------------------------- /XYShape/xypolygongraphicsitem.h: -------------------------------------------------------------------------------- 1 | #ifndef XYPOLYGONGRAPHICSITEM_H 2 | #define XYPOLYGONGRAPHICSITEM_H 3 | 4 | #include "xymovablegraphicsitem.h" 5 | 6 | class XYPolygonGraphicsitem : public XYMovableGraphicsItem 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit XYPolygonGraphicsitem(QGraphicsItem *parent = 0); 11 | ~XYPolygonGraphicsitem(); 12 | 13 | QRectF boundingRect() const Q_DECL_OVERRIDE; 14 | void paint(QPainter *painter, 15 | const QStyleOptionGraphicsItem *option, 16 | QWidget *w) Q_DECL_OVERRIDE; 17 | 18 | private: 19 | QList allPoints; 20 | 21 | friend class XYGraphicsScene; 22 | }; 23 | 24 | #endif // XYPOLYGONGRAPHICSITEM_H 25 | -------------------------------------------------------------------------------- /XYShape/xyrectgraphicsitem.cpp: -------------------------------------------------------------------------------- 1 | #include "xyrectgraphicsitem.h" 2 | 3 | XYRectGraphicsItem::XYRectGraphicsItem(const QRectF &rect, QGraphicsItem *parent) 4 | : XYMovableGraphicsItem(parent), moRect(rect) 5 | { 6 | 7 | } 8 | 9 | QRectF XYRectGraphicsItem::boundingRect() const 10 | { 11 | return QRectF(moRect.x(), moRect.y(), 12 | moRect.width() + 1, moRect.height() + 1); 13 | } 14 | 15 | void XYRectGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w) 16 | { 17 | XYMovableGraphicsItem::paint(painter, option, w); 18 | painter->drawRect(moRect); 19 | } 20 | -------------------------------------------------------------------------------- /XYShape/xyrectgraphicsitem.h: -------------------------------------------------------------------------------- 1 | #ifndef XYGRAPHICSRECTITEM_H 2 | #define XYGRAPHICSRECTITEM_H 3 | 4 | #include "xymovablegraphicsitem.h" 5 | 6 | class XYRectGraphicsItem : public XYMovableGraphicsItem 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit XYRectGraphicsItem(const QRectF &rect = QRectF(), QGraphicsItem *parent = 0); 11 | 12 | QRectF boundingRect() const Q_DECL_OVERRIDE; 13 | void paint(QPainter *painter, 14 | const QStyleOptionGraphicsItem *option, 15 | QWidget *w) Q_DECL_OVERRIDE; 16 | 17 | private: 18 | QRectF moRect; 19 | 20 | friend class XYGraphicsScene; 21 | }; 22 | 23 | #endif // XYGRAPHICSRECTITEM_H 24 | -------------------------------------------------------------------------------- /XYShape/xyshapegraphicsitem.cpp: -------------------------------------------------------------------------------- 1 | #include "xyshapegraphicsitem.h" 2 | 3 | XYShapeGraphicsItem::XYShapeGraphicsItem(QGraphicsItem *parent) 4 | : QAbstractGraphicsShapeItem(parent) 5 | { 6 | creating = true; 7 | } 8 | 9 | QRectF XYShapeGraphicsItem::boundingRect() const 10 | { 11 | return QRectF(); 12 | } 13 | 14 | void XYShapeGraphicsItem::paint(QPainter *painter, 15 | const QStyleOptionGraphicsItem *option, 16 | QWidget *) 17 | { 18 | painter->setRenderHints(QPainter::Antialiasing); 19 | QPen pen = this->pen(); 20 | paintPen = this->pen(); 21 | if (option->state & QStyle::State_MouseOver 22 | || creating) 23 | { 24 | pen.setColor(QColor("red")); 25 | } 26 | 27 | painter->setPen(pen); 28 | painter->setFont(getFont()); 29 | painter->setBrush(brush()); 30 | } 31 | 32 | bool XYShapeGraphicsItem::isValid() 33 | { 34 | return true; 35 | } 36 | 37 | int XYShapeGraphicsItem::type() const 38 | { 39 | return XYSHAPE; 40 | } 41 | 42 | QPen XYShapeGraphicsItem::getPaintPen() const 43 | { 44 | return paintPen; 45 | } 46 | 47 | QLineF XYShapeGraphicsItem::getEllipseAndLineNodes(qreal k, qreal b, qreal c, qreal d, qreal r) 48 | { 49 | // 求圆和直线的交点坐标 50 | // y = kx +b 51 | // (x+c)^2 + (y+d)^2 = r^2 52 | qreal temp1 = sqrt((k*k+1)*r*r - c*c*k*k + (2*c*d + 2*b*c)*k - d*d -2*b*d -b*b); 53 | qreal temp2 = (d+b)*k+c; 54 | qreal temp3 = k*k + 1; 55 | qreal x1 = -(temp1 + temp2) / temp3; 56 | qreal x2 = (temp1 - temp2) / temp3; 57 | 58 | qreal temp4 = sqrt(k*k*r*r + r*r - c*c*k*k + 2*c*d*k + 2*b*c*k - d*d - 2*b*d - b*b); 59 | qreal y1 = -(k*(c+temp4) +d*k*k-b) / temp3; 60 | qreal y2 = -(k*(c-temp4) +d*k*k-b) / temp3; 61 | 62 | return QLineF(QPointF(x1, y1), QPointF(x2, y2)); 63 | } 64 | 65 | QLineF XYShapeGraphicsItem::getVerticalLine(const QPointF &start, 66 | const QPointF &end, 67 | qreal distance, 68 | qreal len) 69 | { 70 | // 直线方程: y = kx + b 71 | if (end.y() != start.y() && end.x() != start.x()) // 不垂直X轴 72 | { 73 | qreal k = (start.y() - end.y()) / (start.x() - end.x()); 74 | qreal b = start.y() - k * start.x(); 75 | 76 | qreal c = -start.x(); 77 | qreal d = -start.y(); 78 | qreal r = distance; 79 | // 求圆和直线的交点坐标 80 | QLineF nodes = getEllipseAndLineNodes(k, b, c, d, r); 81 | 82 | qreal x,y; //交点 83 | if (start.x() > end.x()) 84 | { 85 | if (nodes.x1() < nodes.x2()) 86 | { 87 | x = nodes.x1(); 88 | y = nodes.y1(); 89 | } 90 | else 91 | { 92 | x = nodes.x2(); 93 | y = nodes.y2(); 94 | } 95 | } 96 | else 97 | { 98 | if (nodes.x1() > nodes.x2()) 99 | { 100 | x = nodes.x1(); 101 | y = nodes.y1(); 102 | } 103 | else 104 | { 105 | x = nodes.x2(); 106 | y = nodes.y2(); 107 | } 108 | } 109 | 110 | qreal k1 = -1/k; 111 | qreal b1 = y - k1 * x; 112 | qreal c1 = -x; 113 | qreal d1 = -y; 114 | qreal r1 = len / 2; 115 | return getEllipseAndLineNodes(k1, b1, c1, d1, r1); 116 | } 117 | else 118 | { 119 | QLineF line; 120 | int dire; 121 | if (end.x() == start.x()) 122 | { 123 | dire = end.y() > start.y() ? 1:-1; 124 | line = QLineF(QPointF(start.x() - len / 2, start.y() + (distance * dire)), 125 | QPointF(start.x() + len / 2, start.y() + (distance * dire))); 126 | } 127 | else 128 | { 129 | dire = end.x() > start.x() ? 1:-1; 130 | line = QLineF(QPointF(start.x() + (distance * dire), start.y() - len / 2), 131 | QPointF(start.x() + (distance * dire), start.y() + len / 2)); 132 | } 133 | return line; 134 | } 135 | } 136 | 137 | QFont XYShapeGraphicsItem::getFont() const 138 | { 139 | return moFont; 140 | } 141 | 142 | void XYShapeGraphicsItem::setFont(const QFont &value) 143 | { 144 | moFont = value; 145 | } 146 | 147 | -------------------------------------------------------------------------------- /XYShape/xyshapegraphicsitem.h: -------------------------------------------------------------------------------- 1 | #ifndef XYGRAPHICSSHAPEITEM_H 2 | #define XYGRAPHICSSHAPEITEM_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class XYShapeGraphicsItem : public QObject, public QAbstractGraphicsShapeItem 12 | { 13 | Q_OBJECT 14 | public: 15 | enum { XYSHAPE = UserType + 1 }; 16 | explicit XYShapeGraphicsItem(QGraphicsItem *parent = 0); 17 | 18 | QRectF boundingRect() const Q_DECL_OVERRIDE; 19 | void paint(QPainter *painter, 20 | const QStyleOptionGraphicsItem *option, 21 | QWidget *) Q_DECL_OVERRIDE; 22 | virtual bool isValid(); 23 | int type() const; 24 | 25 | QPen getPaintPen() const; 26 | QFont getFont() const; 27 | void setFont(const QFont &value); 28 | 29 | public: 30 | static QLineF getEllipseAndLineNodes(qreal k, qreal b, qreal c, qreal d, qreal r); 31 | static QLineF getVerticalLine(const QPointF &start, // 获取一条直线的垂直线 32 | const QPointF &end, 33 | qreal distance, 34 | qreal len); 35 | 36 | bool creating; 37 | QFont moFont; 38 | QPen paintPen; 39 | 40 | }; 41 | 42 | #endif // XYGRAPHICSSHAPEITEM_H 43 | -------------------------------------------------------------------------------- /XYShape/xytextgraphicsitem.cpp: -------------------------------------------------------------------------------- 1 | #include "xytextgraphicsitem.h" 2 | #include "xygraphicsscene.h" 3 | 4 | XYTextGraphicsItem::XYTextGraphicsItem(const QString &text, QGraphicsItem *parent) 5 | : XYMovableGraphicsItem(parent) 6 | { 7 | meType = XYTEXT; 8 | } 9 | 10 | QRectF XYTextGraphicsItem::boundingRect() const 11 | { 12 | const qreal x1 = startPos.x(); 13 | const qreal x2 = endPos.x(); 14 | const qreal y1 = startPos.y(); 15 | const qreal y2 = endPos.y(); 16 | qreal lx = qMin(x1, x2); 17 | qreal rx = qMax(x1, x2); 18 | qreal ty = qMin(y1, y2); 19 | qreal by = qMax(y1, y2); 20 | return QRectF(lx, ty, rx - lx, by - ty); 21 | } 22 | 23 | void XYTextGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w) 24 | { 25 | XYMovableGraphicsItem::paint(painter, option, w); 26 | if (option->state & QStyle::State_MouseOver 27 | || creating 28 | || selected) 29 | { 30 | painter->setBrush(QColor("white")); 31 | painter->drawRect(boundingRect()); 32 | } 33 | 34 | painter->setPen(pen()); 35 | painter->drawText(boundingRect(), msText); 36 | } 37 | 38 | void XYTextGraphicsItem::startCreateItem(const QPointF &pos) 39 | { 40 | selected = true; 41 | XYMovableGraphicsItem::startCreateItem(pos); 42 | } 43 | 44 | void XYTextGraphicsItem::endCreateItem(const QPointF &pos) 45 | { 46 | XYMovableGraphicsItem::endCreateItem(pos); 47 | if (scene() != NULL) 48 | { 49 | ((XYGraphicsScene *)scene())->showTextEdit(this); 50 | } 51 | } 52 | 53 | void XYTextGraphicsItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent) 54 | { 55 | if (scene() != NULL) 56 | { 57 | ((XYGraphicsScene *)scene())->showTextEdit(this); 58 | } 59 | mouseEvent->accept(); 60 | } 61 | -------------------------------------------------------------------------------- /XYShape/xytextgraphicsitem.h: -------------------------------------------------------------------------------- 1 | #ifndef XYTEXTGRAPHICSITEM_H 2 | #define XYTEXTGRAPHICSITEM_H 3 | 4 | #include "xymovablegraphicsitem.h" 5 | 6 | class XYTextGraphicsItem : public XYMovableGraphicsItem 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit XYTextGraphicsItem(const QString &text = QString(), QGraphicsItem *parent = 0); 11 | 12 | QRectF boundingRect() const Q_DECL_OVERRIDE; 13 | void paint(QPainter *painter, 14 | const QStyleOptionGraphicsItem *option, 15 | QWidget *w) Q_DECL_OVERRIDE; 16 | 17 | virtual void startCreateItem(const QPointF &pos); 18 | virtual void endCreateItem(const QPointF &pos); 19 | 20 | protected: 21 | void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent) Q_DECL_OVERRIDE; 22 | 23 | private: 24 | QFont moFont; 25 | QString msText; 26 | 27 | friend class XYGraphicsScene; 28 | }; 29 | 30 | #endif // XYTEXTGRAPHICSITEM_H 31 | -------------------------------------------------------------------------------- /drawtool.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/drawtool.ico -------------------------------------------------------------------------------- /ico.rc: -------------------------------------------------------------------------------- 1 | #include "winres.h" 2 | #include "version.h" 3 | 4 | // 图标 5 | IDI_ICON1 ICON PRODUCT_ICON 6 | 7 | // 版本信息 8 | VS_VERSION_INFO VERSIONINFO 9 | FILEVERSION FILE_VERSION 10 | PRODUCTVERSION PRODUCT_VERSION 11 | FILEFLAGSMASK 0x3fL 12 | #ifdef _DEBUG 13 | FILEFLAGS 0x1L 14 | #else 15 | FILEFLAGS 0x0L 16 | #endif 17 | FILEOS 0x40004L 18 | FILETYPE 0x1L 19 | FILESUBTYPE 0x0L 20 | BEGIN 21 | BLOCK "StringFileInfo" 22 | BEGIN 23 | BLOCK "080404b0" 24 | BEGIN 25 | VALUE "CompanyName", COMPANY_NAME 26 | VALUE "FileDescription", FILE_DESCRIPTION 27 | VALUE "FileVersion", FILE_VERSION_STR 28 | VALUE "InternalName", INTERNAL_NAME 29 | VALUE "LegalCopyright", LEGAL_COPYRIGHT 30 | VALUE "OriginalFilename", ORIGINAL_FILE_NAME 31 | VALUE "ProductName", PRODUCT_NAME 32 | VALUE "ProductVersion", PRODUCT_VERSION_STR 33 | END 34 | END 35 | BLOCK "VarFileInfo" 36 | BEGIN 37 | VALUE "Translation", 0x804, 1200 38 | END 39 | END -------------------------------------------------------------------------------- /images/arrows.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/arrows.ico -------------------------------------------------------------------------------- /images/backimage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/backimage.jpg -------------------------------------------------------------------------------- /images/cursor.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/cursor.ico -------------------------------------------------------------------------------- /images/delete.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/delete.ico -------------------------------------------------------------------------------- /images/draw.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/draw.ico -------------------------------------------------------------------------------- /images/drawtool.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/drawtool.ico -------------------------------------------------------------------------------- /images/ellipse.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/ellipse.ico -------------------------------------------------------------------------------- /images/images.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | backimage.jpg 4 | draw.ico 5 | ellipse.ico 6 | rect.ico 7 | open.ico 8 | save.ico 9 | line.ico 10 | cursor.ico 11 | arrows.ico 12 | text.ico 13 | delete.ico 14 | settingpen.ico 15 | pixmap.ico 16 | zoomdown.ico 17 | zoomup.ico 18 | drawtool.ico 19 | stick.ico 20 | rotation.ico 21 | polygon.ico 22 | 23 | 24 | -------------------------------------------------------------------------------- /images/line.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/line.ico -------------------------------------------------------------------------------- /images/open.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/open.ico -------------------------------------------------------------------------------- /images/pixmap.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/pixmap.ico -------------------------------------------------------------------------------- /images/polygon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/polygon.ico -------------------------------------------------------------------------------- /images/rect.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/rect.ico -------------------------------------------------------------------------------- /images/rotation.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/rotation.ico -------------------------------------------------------------------------------- /images/save.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/save.ico -------------------------------------------------------------------------------- /images/settingpen.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/settingpen.ico -------------------------------------------------------------------------------- /images/stick.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/stick.ico -------------------------------------------------------------------------------- /images/text.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/text.ico -------------------------------------------------------------------------------- /images/zoomdown.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/zoomdown.ico -------------------------------------------------------------------------------- /images/zoomup.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/images/zoomup.ico -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "mainwindow.h" 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | QApplication a(argc, argv); 9 | MainWindow w; 10 | w.show(); 11 | 12 | return a.exec(); 13 | } 14 | -------------------------------------------------------------------------------- /mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "xygraphicsview.h" 3 | #include "xygraphicsscene.h" 4 | #include "xycanvasgraphicsitem.h" 5 | #include "xyrectgraphicsitem.h" 6 | #include "xypathgraphicsitem.h" 7 | #include "xyellipsegraphicsitem.h" 8 | #include "xypensettingwidget.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | MainWindow::MainWindow(QWidget *parent) 20 | : QMainWindow(parent) 21 | { 22 | scene = new XYGraphicsScene(0, 0, 700, 500); 23 | view = new XYGraphicsView(scene); 24 | scene->setTextEdit(new QTextEdit(view)); 25 | canvas = new XYCanvasGraphicsItem; 26 | canvas->setZValue(-1); 27 | 28 | view->scene()->setBackgroundBrush(QPixmap(":/backimage.jpg")); 29 | 30 | setCentralWidget(view); 31 | 32 | initToolBar(); 33 | 34 | view->installEventFilter(this); 35 | setAcceptDrops(true); 36 | connect(scene, SIGNAL(selectItemChanged(QGraphicsItem*)), 37 | XYPenSettingWidget::getInstance(), SLOT(initWithItem(QGraphicsItem*))); 38 | connect(XYPenSettingWidget::getInstance(), SIGNAL(penChanged(QPen)), 39 | scene, SLOT(slotPenChanged(QPen))); 40 | connect(XYPenSettingWidget::getInstance(), SIGNAL(brushChanged(QBrush)), 41 | scene, SLOT(slotBrushChanged(QBrush))); 42 | connect(XYPenSettingWidget::getInstance(), SIGNAL(fontChanged(QFont)), 43 | scene, SLOT(slotFontChanged(QFont))); 44 | } 45 | 46 | MainWindow::~MainWindow() 47 | { 48 | 49 | } 50 | 51 | void MainWindow::setShape(QAction *act) 52 | { 53 | if (act) 54 | { 55 | scene->setItemMovable(false); 56 | if (act->text() == "Rect") 57 | { 58 | scene->setShape(XYGraphicsScene::RECT); 59 | } 60 | else if (act->text() == "Polygon") 61 | { 62 | scene->setShape(XYGraphicsScene::POLYGON); 63 | } 64 | else if (act->text() == "Path") 65 | { 66 | scene->setShape(XYGraphicsScene::PATH); 67 | } 68 | else if (act->text() == "Ellipse") 69 | { 70 | scene->setShape(XYGraphicsScene::ELLIPSE); 71 | } 72 | else if (act->text() == "Line") 73 | { 74 | scene->setShape(XYGraphicsScene::LINE); 75 | } 76 | else if (act->text() == "Arrows") 77 | { 78 | scene->setShape(XYGraphicsScene::ARROWS); 79 | } 80 | else if (act->text() == "Text") 81 | { 82 | scene->setShape(XYGraphicsScene::TEXT); 83 | } 84 | else if (act->text() == "Pixmap") 85 | { 86 | scene->setShape(XYGraphicsScene::PIXMAP); 87 | } 88 | else if (act->text() == "Cursor") 89 | { 90 | scene->setShape(XYGraphicsScene::CURSOR); 91 | scene->setItemMovable(true); 92 | } 93 | else if (act->text() == "Delete") 94 | { 95 | scene->setShape(XYGraphicsScene::DELETE); 96 | } 97 | } 98 | } 99 | 100 | void MainWindow::openPixmap(const QString &path) 101 | { 102 | if (path.isEmpty()) 103 | { 104 | lastPixmapPath = QFileDialog::getOpenFileName(this, tr("Open File"), 105 | "", 106 | tr("PNG (*.png);;JPG (*.jpg)")); 107 | } 108 | else 109 | { 110 | lastPixmapPath = path; 111 | } 112 | QPixmap pixmap(lastPixmapPath); 113 | if (!pixmap.isNull()) 114 | { 115 | if (canvas->scene()) 116 | { 117 | canvas->scene()->removeItem(canvas); 118 | } 119 | canvas->setPixmap(pixmap); 120 | scene->setSceneRect(pixmap.rect()); 121 | scene->addItem(canvas); 122 | } 123 | } 124 | 125 | void MainWindow::savePixmap() 126 | { 127 | QString path = lastPixmapPath; 128 | if (path.isEmpty()) 129 | { 130 | path = QFileDialog::getSaveFileName(this, tr("Save File"), 131 | "untitled.png", 132 | tr("PNG (*.png);;JPG (*.jpg)")); 133 | } 134 | if (!path.isEmpty()) 135 | { 136 | QPixmap pixmap(scene->sceneRect().width(), scene->sceneRect().height()); 137 | 138 | QPainter painter(&pixmap); 139 | scene->render(&painter); 140 | if (pixmap.save(path, path.mid(path.lastIndexOf(".") + 1).toUpper().toLocal8Bit().data())) 141 | { 142 | lastPixmapPath = path; 143 | } 144 | } 145 | } 146 | 147 | void MainWindow::settingPen() 148 | { 149 | XYPenSettingWidget *penSetting = XYPenSettingWidget::getInstance(); 150 | if (penSetting->isHidden()) 151 | { 152 | penSetting->setVisible(true); 153 | penSetting->raise(); 154 | penSetting->move(pos().x() + width() + 20, 155 | pos().y() + 70); 156 | } 157 | else 158 | { 159 | penSetting->setVisible(false); 160 | } 161 | } 162 | 163 | void MainWindow::closeEvent(QCloseEvent *event) 164 | { 165 | QMessageBox box; 166 | box.setIcon(QMessageBox::Question); 167 | box.setWindowTitle(QStringLiteral("退出确认")); 168 | box.setText(QStringLiteral("是否需要保存当前图片?")); 169 | box.addButton(QMessageBox::Yes)->setText(QStringLiteral("是")); 170 | box.addButton(QMessageBox::No)->setText(QStringLiteral("否")); 171 | box.addButton(QMessageBox::Ignore)->setText(QStringLiteral("忽略")); 172 | int ret = box.exec(); 173 | switch (ret) { 174 | case QMessageBox::Yes: 175 | savePixmap(); 176 | break; 177 | case QMessageBox::No: 178 | event->accept(); 179 | break; 180 | case QMessageBox::Ignore: 181 | event->ignore(); 182 | return; 183 | break; 184 | default: 185 | // should never be reached 186 | break; 187 | } 188 | 189 | QMainWindow::closeEvent(event); 190 | } 191 | 192 | bool MainWindow::eventFilter(QObject *watched, QEvent *event) 193 | { 194 | if (watched == view) 195 | { 196 | if (event->type() == QEvent::Drop) 197 | { 198 | QDropEvent *drag = (QDropEvent *)event; 199 | const QMimeData *mimeData = drag->mimeData(); 200 | if (mimeData->hasUrls()) 201 | { 202 | QList urlList = mimeData->urls(); 203 | if (urlList.size() > 1) 204 | { 205 | QMessageBox::warning(this, QStringLiteral("警告"), 206 | QStringLiteral("只能处理一个文件!")); 207 | return true; 208 | } 209 | else 210 | { 211 | if (scene->getShape() == XYGraphicsScene::PIXMAP) 212 | { 213 | QString path = urlList.at(0).toLocalFile(); 214 | scene->addPixmapItem(path, drag->posF()); 215 | } 216 | else 217 | { 218 | QString path = urlList.at(0).toLocalFile(); 219 | openPixmap(path); 220 | } 221 | } 222 | } 223 | return true; 224 | } 225 | else if (event->type() == QEvent::DragEnter) 226 | { 227 | QDragEnterEvent *drag = (QDragEnterEvent *)event; 228 | drag->acceptProposedAction(); 229 | return true; 230 | } 231 | } 232 | return QMainWindow::eventFilter(watched, event); 233 | } 234 | 235 | void MainWindow::initToolBar() 236 | { 237 | QToolBar *bar = new QToolBar; 238 | QActionGroup *shapeGroup = new QActionGroup(this); 239 | 240 | QAction *act = bar->addAction(QIcon(":/open.ico"), QString("Open File"), this, SLOT(openPixmap())); 241 | act->setToolTip(QStringLiteral("打开图片")); 242 | act = bar->addAction(QIcon(":/save.ico"), QString("Save File"), this, SLOT(savePixmap())); 243 | act->setToolTip(QStringLiteral("保存图片")); 244 | act = bar->addAction(QIcon(":/cursor.ico"), QString("Cursor")); 245 | act->setToolTip(QStringLiteral("移动图元")); 246 | act->setCheckable(true); 247 | act->setChecked(true); 248 | scene->setShape(XYGraphicsScene::CURSOR); 249 | shapeGroup->addAction(act); 250 | act = bar->addAction(QIcon(":/rect.ico"), QString("Rect")); 251 | act->setToolTip(QStringLiteral("绘制矩形")); 252 | act->setCheckable(true); 253 | shapeGroup->addAction(act); 254 | act = bar->addAction(QIcon(":/polygon.ico"), QString("Polygon")); 255 | act->setToolTip(QStringLiteral("绘制多边形")); 256 | act->setCheckable(true); 257 | shapeGroup->addAction(act); 258 | act = bar->addAction(QIcon(":/ellipse.ico"), QString("Ellipse")); 259 | act->setToolTip(QStringLiteral("绘制椭圆")); 260 | act->setCheckable(true); 261 | shapeGroup->addAction(act); 262 | act = bar->addAction(QIcon(":/arrows.ico"), QString("Arrows")); 263 | act->setToolTip(QStringLiteral("绘制箭头")); 264 | act->setCheckable(true); 265 | shapeGroup->addAction(act); 266 | act = bar->addAction(QIcon(":/line.ico"), QString("Line")); 267 | act->setToolTip(QStringLiteral("绘制直线")); 268 | act->setCheckable(true); 269 | shapeGroup->addAction(act); 270 | act = bar->addAction(QIcon(":/draw.ico"), QString("Path")); 271 | act->setToolTip(QStringLiteral("绘制自定义曲线")); 272 | act->setCheckable(true); 273 | shapeGroup->addAction(act); 274 | act = bar->addAction(QIcon(":/text.ico"), QString("Text")); 275 | act->setToolTip(QStringLiteral("绘制文本")); 276 | act->setCheckable(true); 277 | shapeGroup->addAction(act); 278 | act = bar->addAction(QIcon(":/pixmap.ico"), QString("Pixmap")); 279 | act->setToolTip(QStringLiteral("插入图片模式下,直接拖拽图片进入窗口即可!")); 280 | act->setCheckable(true); 281 | shapeGroup->addAction(act); 282 | act = bar->addAction(QIcon(":/stick.ico"), QString("Stick"), 283 | scene, SLOT(stickItem())); 284 | act->setToolTip(QStringLiteral("图元置顶")); 285 | act = bar->addAction(QIcon(":/zoomup.ico"), QString("Zoom Up"), 286 | scene, SLOT(zoomUpItem())); 287 | act->setAutoRepeat(true); 288 | act->setShortcut(QKeySequence(tr("Ctrl+U"))); 289 | act->setToolTip(QStringLiteral("放大图元")); 290 | act = bar->addAction(QIcon(":/zoomdown.ico"), QString("Zoom Down"), 291 | scene, SLOT(zoomDownItem())); 292 | act->setAutoRepeat(true); 293 | act->setShortcut(QKeySequence(tr("Ctrl+D"))); 294 | act->setToolTip(QStringLiteral("缩小图元")); 295 | act = bar->addAction(QIcon(":/rotation.ico"), QString("Rotation"), 296 | scene, SLOT(rotationItem())); 297 | act->setAutoRepeat(true); 298 | act->setShortcut(QKeySequence(tr("Ctrl+R"))); 299 | act->setToolTip(QStringLiteral("旋转图元")); 300 | act = bar->addAction(QIcon(":/settingpen.ico"), QString("SettingPen"), 301 | this, SLOT(settingPen())); 302 | act->setToolTip(QStringLiteral("设置画笔画刷字体")); 303 | act = bar->addAction(QIcon(":/delete.ico"), QString("Delete")); 304 | act->setToolTip(QStringLiteral("删除图元")); 305 | act->setCheckable(true); 306 | shapeGroup->addAction(act); 307 | 308 | connect(shapeGroup, SIGNAL(triggered(QAction *)), 309 | this, SLOT(setShape(QAction *))); 310 | 311 | addToolBar(bar); 312 | } 313 | -------------------------------------------------------------------------------- /mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | 6 | class XYGraphicsView; 7 | class XYGraphicsScene; 8 | class XYCanvasGraphicsItem; 9 | class MainWindow : public QMainWindow 10 | { 11 | Q_OBJECT 12 | public: 13 | MainWindow(QWidget *parent = 0); 14 | ~MainWindow(); 15 | 16 | public slots: 17 | void setShape(QAction *act); 18 | void openPixmap(const QString &path = QString()); 19 | void savePixmap(); 20 | void settingPen(); 21 | 22 | protected: 23 | void closeEvent(QCloseEvent *event); 24 | bool eventFilter(QObject *watched, QEvent *event); 25 | 26 | private: 27 | void initToolBar(); 28 | 29 | private: 30 | XYGraphicsView *view; 31 | XYGraphicsScene *scene; 32 | XYCanvasGraphicsItem *canvas; 33 | QString lastPixmapPath; 34 | 35 | }; 36 | 37 | #endif // MAINWINDOW_H 38 | -------------------------------------------------------------------------------- /version.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoyanLG/Draw-Tool/158ade78f519d6bc2a5f0f12d0c4ff9533c73419/version.h -------------------------------------------------------------------------------- /xygraphicsscene.cpp: -------------------------------------------------------------------------------- 1 | #include "xygraphicsscene.h" 2 | #include "xycanvasgraphicsitem.h" 3 | #include "xyrectgraphicsitem.h" 4 | #include "xypolygongraphicsitem.h" 5 | #include "xypathgraphicsitem.h" 6 | #include "xyellipsegraphicsitem.h" 7 | #include "xylinegraphicsitem.h" 8 | #include "xyarrowsgraphicsitem.h" 9 | #include "xytextgraphicsitem.h" 10 | #include "xypixmapgraphicsitem.h" 11 | #include "xypensettingwidget.h" 12 | #include 13 | #include 14 | 15 | XYGraphicsScene::XYGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObject *parent) 16 | : QGraphicsScene(x, y, width, height, parent) 17 | { 18 | meShape = CURSOR; 19 | haveKeyboardItem = NULL; 20 | selectItem = NULL; 21 | textEdit = NULL; 22 | setItemIndexMethod(QGraphicsScene::NoIndex); // 这个函数必须调,不然会导致程序异常 23 | } 24 | 25 | XYGraphicsScene::~XYGraphicsScene() 26 | { 27 | 28 | } 29 | 30 | XYGraphicsScene::SHAPE XYGraphicsScene::getShape() 31 | { 32 | return meShape; 33 | } 34 | 35 | void XYGraphicsScene::setShape(XYGraphicsScene::SHAPE shape) 36 | { 37 | meShape = shape; 38 | } 39 | 40 | void XYGraphicsScene::setItemMovable(bool movable) 41 | { 42 | XYMovableGraphicsItem::acceptMouse = movable; 43 | } 44 | 45 | void XYGraphicsScene::setTextEdit(QTextEdit *textEdit) 46 | { 47 | this->textEdit = textEdit; 48 | if (this->textEdit != NULL) 49 | { 50 | this->textEdit->setVisible(false); 51 | connect(this->textEdit, SIGNAL(textChanged()), this, SLOT(setItemText())); 52 | } 53 | } 54 | 55 | void XYGraphicsScene::addPixmapItem(const QString &file, const QPointF &pos) 56 | { 57 | QPixmap pixmap(file); 58 | if (!pixmap.isNull()) 59 | { 60 | XYPixmapGraphicsItem *item = new XYPixmapGraphicsItem(pixmap); 61 | item->setPos(pos - QPointF(pixmap.width() / 2, pixmap.height())); 62 | this->addItem(item); 63 | } 64 | } 65 | 66 | void XYGraphicsScene::savePixmap(const QString &path) 67 | { 68 | QPixmap pixmap; 69 | QPainter painter(&pixmap); 70 | this->render(&painter); 71 | pixmap.save(path); 72 | } 73 | 74 | void XYGraphicsScene::showTextEdit(XYTextGraphicsItem *item) 75 | { 76 | if (textEdit != NULL) 77 | { 78 | haveKeyboardItem = item; 79 | qreal x_offset = 0; 80 | qreal y_offset = 0; 81 | if (!views().isEmpty()) 82 | { 83 | x_offset = views().at(0)->width(); 84 | y_offset = views().at(0)->height(); 85 | } 86 | if (x_offset > width()) 87 | { 88 | x_offset = (x_offset - width()) / 2; 89 | } 90 | if (y_offset > height()) 91 | { 92 | y_offset = (y_offset - height()) / 2; 93 | } 94 | x_offset = x_offset * item->scale(); 95 | y_offset = y_offset * item->scale(); 96 | textEdit->resize(item->sceneBoundingRect().width(), 97 | item->sceneBoundingRect().height()); 98 | textEdit->move(item->sceneBoundingRect().x() + x_offset, 99 | item->sceneBoundingRect().y() + y_offset); 100 | textEdit->setText(((XYTextGraphicsItem *)item)->msText); 101 | textEdit->setFocus(); 102 | textEdit->setVisible(true); 103 | } 104 | } 105 | 106 | void XYGraphicsScene::stickItem() 107 | { 108 | static int z = 1; 109 | if (selectItem) 110 | { 111 | selectItem->setZValue(z++); 112 | } 113 | } 114 | 115 | void XYGraphicsScene::zoomUpItem() 116 | { 117 | if (selectItem) 118 | { 119 | if (textEdit != NULL && !textEdit->isHidden()) 120 | { 121 | textEdit->setVisible(false); 122 | } 123 | selectItem->setScale(selectItem->scale() + 0.02); 124 | } 125 | } 126 | 127 | void XYGraphicsScene::zoomDownItem() 128 | { 129 | if (selectItem) 130 | { 131 | if (textEdit != NULL && !textEdit->isHidden()) 132 | { 133 | textEdit->setVisible(false); 134 | } 135 | qreal cur = selectItem->scale() - 0.02; 136 | if (cur < 0) 137 | { 138 | cur = 0; 139 | } 140 | selectItem->setScale(cur); 141 | } 142 | } 143 | 144 | void XYGraphicsScene::rotationItem() 145 | { 146 | if (selectItem) 147 | { 148 | qreal cur = selectItem->rotation() + 15; 149 | if (qApp->keyboardModifiers() & Qt::ControlModifier) 150 | { 151 | cur = selectItem->rotation() + 0.5; 152 | } 153 | if (cur > 360) 154 | { 155 | cur -= 360; 156 | } 157 | selectItem->setTransformOriginPoint(selectItem->boundingRect().center()); 158 | selectItem->setRotation(cur); 159 | } 160 | } 161 | 162 | void XYGraphicsScene::setItemText() 163 | { 164 | if (textEdit != NULL && haveKeyboardItem != NULL) 165 | { 166 | ((XYTextGraphicsItem *)haveKeyboardItem)->msText = textEdit->toPlainText(); 167 | } 168 | } 169 | 170 | void XYGraphicsScene::slotPenChanged(const QPen &pen) 171 | { 172 | if (textEdit != NULL && !textEdit->isHidden()) 173 | { 174 | textEdit->setTextColor(pen.color()); 175 | textEdit->setPlainText(textEdit->toPlainText()); 176 | } 177 | if (selectItem != NULL 178 | && (selectItem->type() == XYMovableGraphicsItem::XYSHAPE 179 | || selectItem->type() == XYMovableGraphicsItem::XYSHAPEMOVABLE 180 | || selectItem->type() == XYMovableGraphicsItem::XYTEXT)) 181 | { 182 | XYShapeGraphicsItem *item = (XYShapeGraphicsItem *)selectItem; 183 | item->setPen(pen); 184 | item->update(); 185 | } 186 | } 187 | 188 | void XYGraphicsScene::slotBrushChanged(const QBrush &brush) 189 | { 190 | if (selectItem != NULL 191 | && (selectItem->type() == XYMovableGraphicsItem::XYSHAPE 192 | || selectItem->type() == XYMovableGraphicsItem::XYSHAPEMOVABLE 193 | || selectItem->type() == XYMovableGraphicsItem::XYTEXT)) 194 | { 195 | XYShapeGraphicsItem *item = (XYShapeGraphicsItem *)selectItem; 196 | item->setBrush(brush); 197 | item->update(); 198 | } 199 | } 200 | 201 | void XYGraphicsScene::slotFontChanged(const QFont &font) 202 | { 203 | if (textEdit != NULL && !textEdit->isHidden()) 204 | { 205 | textEdit->setFont(font); 206 | } 207 | if (selectItem != NULL 208 | && (selectItem->type() == XYMovableGraphicsItem::XYSHAPE 209 | || selectItem->type() == XYMovableGraphicsItem::XYSHAPEMOVABLE 210 | || selectItem->type() == XYMovableGraphicsItem::XYTEXT)) 211 | { 212 | XYShapeGraphicsItem *item = (XYShapeGraphicsItem *)selectItem; 213 | item->setFont(font); 214 | item->update(); 215 | } 216 | } 217 | 218 | bool XYGraphicsScene::event(QEvent *event) 219 | { 220 | static XYMovableGraphicsItem *item = NULL; 221 | 222 | QGraphicsScene::event(event); 223 | if (event->isAccepted()) 224 | { 225 | if (meShape == POLYGON) 226 | { 227 | return paintPolygon(event); 228 | } 229 | return true; 230 | } 231 | if (meShape == POLYGON) 232 | { 233 | return paintPolygon(event); 234 | } 235 | 236 | QGraphicsSceneMouseEvent *mouse_event = (QGraphicsSceneMouseEvent *)event; 237 | if (event->type() == QEvent::GraphicsSceneMousePress) 238 | { 239 | if (mouse_event->button() == Qt::LeftButton) 240 | { 241 | item = getCurDrawshapeItem(); 242 | setGraphicsItemStartPos(item, mouse_event->scenePos()); 243 | if (item) 244 | { 245 | this->addItem(item); 246 | } 247 | } 248 | else if (mouse_event->button() == Qt::RightButton) 249 | { 250 | if (item) 251 | { 252 | this->removeItem(item); 253 | delete item; 254 | item = NULL; 255 | } 256 | } 257 | event->accept(); 258 | } 259 | else if (event->type() == QEvent::GraphicsSceneMouseRelease) 260 | { 261 | if (mouse_event->button() == Qt::LeftButton) 262 | { 263 | if (item) 264 | { 265 | setGraphicsItemMovePos(item, mouse_event->scenePos()); 266 | this->removeItem(item); 267 | if (item->isValid()) 268 | { 269 | this->addItem(item); 270 | setGraphicsItemEndPos(item, mouse_event->scenePos()); 271 | if (selectItem != NULL 272 | && (selectItem->type() == XYMovableGraphicsItem::XYSHAPE 273 | || selectItem->type() == XYMovableGraphicsItem::XYSHAPEMOVABLE 274 | || selectItem->type() == XYMovableGraphicsItem::XYTEXT)) 275 | { 276 | ((XYMovableGraphicsItem *)selectItem)->selected = false; 277 | } 278 | selectItem = item; 279 | } 280 | else 281 | { 282 | delete item; 283 | } 284 | item = NULL; 285 | } 286 | } 287 | event->accept(); 288 | } 289 | else if (event->type() == QEvent::GraphicsSceneMouseMove) 290 | { 291 | if (item) 292 | { 293 | setGraphicsItemMovePos(item, mouse_event->scenePos()); 294 | update(this->sceneRect()); 295 | } 296 | event->accept(); 297 | } 298 | return true; 299 | } 300 | 301 | void XYGraphicsScene::wheelEvent(QGraphicsSceneWheelEvent *event) 302 | { 303 | if (selectItem != NULL) 304 | { 305 | if (event->delta() > 0) 306 | { 307 | zoomUpItem(); 308 | } 309 | else 310 | { 311 | zoomDownItem(); 312 | } 313 | event->accept(); 314 | } 315 | } 316 | 317 | void XYGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) 318 | { 319 | if (mouseEvent->button() == Qt::LeftButton) 320 | { 321 | QList items = this->items(); 322 | for (int i = 0; i < items.size(); ++i) 323 | { 324 | if (((XYMovableGraphicsItem *)items.at(i))->selected) 325 | { 326 | ((XYMovableGraphicsItem *)items.at(i))->mouseMoveEvent(mouseEvent); 327 | } 328 | } 329 | } 330 | QGraphicsScene::mouseMoveEvent(mouseEvent); 331 | } 332 | 333 | void XYGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) 334 | { 335 | QGraphicsItem *item = itemAt(mouseEvent->scenePos(), QTransform()); 336 | if (item != NULL && item->type() == XYCanvasGraphicsItem::XYCANVAS) 337 | { 338 | item = NULL; 339 | } 340 | 341 | if (selectItem != item) 342 | { 343 | emit selectItemChanged(item); 344 | } 345 | selectItem = item; 346 | 347 | switch (meShape) 348 | { 349 | case DELETE: 350 | if (item != NULL) 351 | { 352 | removeItem(item); 353 | delete item; 354 | selectItem = NULL; 355 | } 356 | return; 357 | default: 358 | break; 359 | } 360 | 361 | if (textEdit != NULL && !textEdit->isHidden()) 362 | { 363 | textEdit->setVisible(false); 364 | } 365 | 366 | // 去掉非点击item选中 367 | QList items = this->items(); 368 | for (int i = 0; i < items.size(); ++i) 369 | { 370 | switch (items.at(i)->type()) 371 | { 372 | case XYMovableGraphicsItem::XYSHAPE: 373 | case XYMovableGraphicsItem::XYSHAPEMOVABLE: 374 | case XYMovableGraphicsItem::XYTEXT: 375 | if (items.at(i) != item) 376 | { 377 | ((XYMovableGraphicsItem *)items.at(i))->selected = false; 378 | } 379 | else if (items.at(i) == item) 380 | { 381 | ((XYMovableGraphicsItem *)items.at(i))->selected = true; 382 | } 383 | 384 | break; 385 | case XYCanvasGraphicsItem::XYCANVAS: 386 | break; 387 | default: 388 | break; 389 | } 390 | } 391 | update(sceneRect()); 392 | QGraphicsScene::mousePressEvent(mouseEvent); 393 | } 394 | 395 | bool XYGraphicsScene::paintPolygon(QEvent *event) 396 | { 397 | static XYPolygonGraphicsitem *item = NULL; 398 | QGraphicsSceneMouseEvent *mouse_event = (QGraphicsSceneMouseEvent *)event; 399 | if (event->type() == QEvent::GraphicsSceneMousePress) 400 | { 401 | if (mouse_event->button() == Qt::LeftButton) 402 | { 403 | if (item == NULL) 404 | { 405 | item = (XYPolygonGraphicsitem *)getCurDrawshapeItem(); 406 | if (item) 407 | { 408 | this->addItem(item); 409 | setGraphicsItemStartPos(item, mouse_event->scenePos()); 410 | } 411 | } 412 | else 413 | { 414 | item->allPoints.append(mouse_event->scenePos()); 415 | } 416 | } 417 | else if (mouse_event->button() == Qt::RightButton) 418 | { 419 | if (item != NULL) 420 | { 421 | setGraphicsItemEndPos(item, mouse_event->scenePos()); 422 | this->removeItem(item); 423 | this->addItem(item); 424 | item = NULL; 425 | } 426 | } 427 | } 428 | else if (event->type() == QEvent::GraphicsSceneMouseMove) 429 | { 430 | if (item != NULL) 431 | { 432 | item->endPos = mouse_event->scenePos(); 433 | update(sceneRect()); 434 | } 435 | } 436 | return true; 437 | } 438 | 439 | QPen XYGraphicsScene::getCurPen() 440 | { 441 | XYPenSettingWidget *penSetting = XYPenSettingWidget::getInstance(); 442 | return penSetting->getMoPen(); 443 | } 444 | 445 | QFont XYGraphicsScene::getCurFont() 446 | { 447 | XYPenSettingWidget *penSetting = XYPenSettingWidget::getInstance(); 448 | return penSetting->getMoFont(); 449 | } 450 | 451 | QBrush XYGraphicsScene::getCurBrush() 452 | { 453 | XYPenSettingWidget *penSetting = XYPenSettingWidget::getInstance(); 454 | return penSetting->getMoBrush(); 455 | } 456 | 457 | XYMovableGraphicsItem *XYGraphicsScene::getCurDrawshapeItem() 458 | { 459 | XYMovableGraphicsItem *item = NULL; 460 | switch (meShape) 461 | { 462 | case RECT: 463 | item = new XYRectGraphicsItem; 464 | break; 465 | case POLYGON: 466 | item = new XYPolygonGraphicsitem; 467 | break; 468 | case PATH: 469 | item = new XYPathGraphicsItem; 470 | break; 471 | case ELLIPSE: 472 | item = new XYEllipseGraphicsItem; 473 | break; 474 | case LINE: 475 | item = new XYLineGraphicsItem; 476 | break; 477 | case ARROWS: 478 | item = new XYArrowsGraphicsItem; 479 | break; 480 | case TEXT: 481 | item = new XYTextGraphicsItem; 482 | if (textEdit != NULL) 483 | { 484 | textEdit->setTextColor(getCurPen().color()); 485 | textEdit->setFont(getCurFont()); 486 | } 487 | break; 488 | case PIXMAP: 489 | break; 490 | default: 491 | break; 492 | } 493 | 494 | if (item != NULL) 495 | { 496 | item->setPen(getCurPen()); 497 | item->setFont(getCurFont()); 498 | item->setBrush(getCurBrush()); 499 | } 500 | return item; 501 | } 502 | 503 | void XYGraphicsScene::setGraphicsItemStartPos(XYMovableGraphicsItem *item, const QPointF &pos) 504 | { 505 | switch (meShape) 506 | { 507 | case PATH: 508 | { 509 | XYPathGraphicsItem *pathItem = static_cast(item); 510 | if (pathItem) 511 | { 512 | pathItem->moPath.moveTo(pos); 513 | } 514 | break; 515 | } 516 | case RECT: 517 | case ELLIPSE: 518 | case LINE: 519 | case TEXT: 520 | break; 521 | case ARROWS: 522 | case POLYGON: 523 | { 524 | XYMovableGraphicsItem *arrowsItem = static_cast(item); 525 | arrowsItem->endPos = pos; 526 | break; 527 | } 528 | default: 529 | break; 530 | } 531 | XYMovableGraphicsItem *moveItem = static_cast(item); 532 | if (moveItem) 533 | { 534 | moveItem->startCreateItem(pos); 535 | } 536 | } 537 | 538 | void XYGraphicsScene::setGraphicsItemEndPos(XYMovableGraphicsItem *item, const QPointF &pos) 539 | { 540 | XYMovableGraphicsItem *moveItem = static_cast(item); 541 | if (moveItem) 542 | { 543 | moveItem->endCreateItem(pos); 544 | } 545 | } 546 | 547 | void XYGraphicsScene::setGraphicsItemMovePos(XYMovableGraphicsItem *item, const QPointF &pos) 548 | { 549 | item->endPos = pos; 550 | switch (meShape) 551 | { 552 | case RECT: 553 | { 554 | XYRectGraphicsItem *rectItem = static_cast(item); 555 | if (rectItem) 556 | { 557 | rectItem->moRect = QRectF(qMin(rectItem->startPos.x(), pos.x()), 558 | qMin(rectItem->startPos.y(), pos.y()), 559 | qAbs(rectItem->startPos.x() - pos.x()), 560 | qAbs(rectItem->startPos.y() - pos.y())); 561 | } 562 | break; 563 | } 564 | case POLYGON: 565 | { 566 | XYPolygonGraphicsitem *pathItem = static_cast(item); 567 | if (pathItem) 568 | { 569 | pathItem->allPoints.append(pos); 570 | } 571 | break; 572 | } 573 | case PATH: 574 | { 575 | XYPathGraphicsItem *pathItem = static_cast(item); 576 | if (pathItem) 577 | { 578 | pathItem->moPath.lineTo(pos); 579 | } 580 | break; 581 | } 582 | case ELLIPSE: 583 | { 584 | XYEllipseGraphicsItem *ellipseItem = static_cast(item); 585 | if (ellipseItem) 586 | { 587 | ellipseItem->moRect = QRectF(qMin(ellipseItem->startPos.x(), pos.x()), 588 | qMin(ellipseItem->startPos.y(), pos.y()), 589 | qAbs(ellipseItem->startPos.x() - pos.x()), 590 | qAbs(ellipseItem->startPos.y() - pos.y())); 591 | } 592 | break; 593 | } 594 | case LINE: 595 | { 596 | XYLineGraphicsItem *lineItem = static_cast(item); 597 | if (lineItem) 598 | { 599 | lineItem->moLine = QLineF(lineItem->startPos, pos); 600 | } 601 | break; 602 | } 603 | case ARROWS: 604 | case TEXT: 605 | { 606 | XYMovableGraphicsItem *generalItem = static_cast(item); 607 | if (generalItem) 608 | { 609 | generalItem->duringCreateItem(pos); 610 | } 611 | break; 612 | } 613 | default: 614 | break; 615 | } 616 | } 617 | -------------------------------------------------------------------------------- /xygraphicsscene.h: -------------------------------------------------------------------------------- 1 | #ifndef XYGRAPHICSSCENE_H 2 | #define XYGRAPHICSSCENE_H 3 | 4 | #include 5 | #include 6 | 7 | class XYMovableGraphicsItem; 8 | class XYTextGraphicsItem; 9 | class XYGraphicsScene : public QGraphicsScene 10 | { 11 | Q_OBJECT 12 | public: 13 | enum SHAPE{RECT, POLYGON, PATH, ELLIPSE, LINE, ARROWS, TEXT, PIXMAP, CURSOR, DELETE}; 14 | explicit XYGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObject *parent = Q_NULLPTR); 15 | ~XYGraphicsScene(); 16 | SHAPE getShape(); 17 | void setShape(SHAPE shape); 18 | void setItemMovable(bool movable); 19 | 20 | void setTextEdit(QTextEdit *textEdit); 21 | void addPixmapItem(const QString &file, const QPointF &pos); 22 | void savePixmap(const QString &path); 23 | void showTextEdit(XYTextGraphicsItem *item); 24 | 25 | signals: 26 | void selectItemChanged(QGraphicsItem *selectItem); 27 | 28 | public slots: 29 | void stickItem(); 30 | void zoomUpItem(); 31 | void zoomDownItem(); 32 | void rotationItem(); 33 | void setItemText(); 34 | void slotPenChanged(const QPen &pen); 35 | void slotBrushChanged(const QBrush &brush); 36 | void slotFontChanged(const QFont &font); 37 | 38 | protected: 39 | bool event(QEvent *event); 40 | void wheelEvent(QGraphicsSceneWheelEvent *event); 41 | void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent); 42 | void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); 43 | 44 | bool paintPolygon(QEvent *event); 45 | 46 | private: 47 | QPen getCurPen(); 48 | QFont getCurFont(); 49 | QBrush getCurBrush(); 50 | XYMovableGraphicsItem *getCurDrawshapeItem(); 51 | void setGraphicsItemStartPos(XYMovableGraphicsItem *item, const QPointF &pos); 52 | void setGraphicsItemEndPos(XYMovableGraphicsItem *item, const QPointF &pos); 53 | void setGraphicsItemMovePos(XYMovableGraphicsItem *item, const QPointF &pos); 54 | 55 | private: 56 | SHAPE meShape; 57 | QTextEdit *textEdit; 58 | XYTextGraphicsItem *haveKeyboardItem; 59 | QGraphicsItem *selectItem; 60 | }; 61 | 62 | #endif // XYGRAPHICSSCENE_H 63 | -------------------------------------------------------------------------------- /xygraphicsview.cpp: -------------------------------------------------------------------------------- 1 | #include "xygraphicsview.h" 2 | #include 3 | 4 | XYGraphicsView::XYGraphicsView(QGraphicsScene *scene) 5 | : QGraphicsView(scene) 6 | { 7 | 8 | } 9 | 10 | XYGraphicsView::~XYGraphicsView() 11 | { 12 | 13 | } 14 | 15 | void XYGraphicsView::resizeEvent(QResizeEvent *event) 16 | { 17 | scene()->setSceneRect(QRect(QPoint(0, 0), event->size())); 18 | QGraphicsView::resizeEvent(event); 19 | } 20 | 21 | void XYGraphicsView::wheelEvent(QWheelEvent *event) 22 | { 23 | QGraphicsView::wheelEvent(event); 24 | if (event->isAccepted()) 25 | { 26 | return; 27 | } 28 | qreal unit = 0.02; 29 | QMatrix mat = matrix(); 30 | if (event->delta() > 0) 31 | { 32 | mat.scale(1 + unit, 1 + unit); 33 | } 34 | else 35 | { 36 | mat.scale(1 - unit, 1 - unit); 37 | } 38 | setMatrix(mat); 39 | } 40 | 41 | void XYGraphicsView::dragEnterEvent(QDragEnterEvent *event) 42 | { 43 | // QTBUG 没有重写这个函数接收不到事件 44 | } 45 | -------------------------------------------------------------------------------- /xygraphicsview.h: -------------------------------------------------------------------------------- 1 | #ifndef XYGRAPHICSVIEW_H 2 | #define XYGRAPHICSVIEW_H 3 | 4 | #include 5 | 6 | class XYGraphicsView : public QGraphicsView 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit XYGraphicsView(QGraphicsScene *scene = 0); 11 | ~XYGraphicsView(); 12 | 13 | protected: 14 | void resizeEvent(QResizeEvent *event); 15 | void wheelEvent(QWheelEvent *event); 16 | void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE; 17 | 18 | }; 19 | 20 | #endif // XYGRAPHICSVIEW_H 21 | -------------------------------------------------------------------------------- /xymovablewidget.cpp: -------------------------------------------------------------------------------- 1 | #include "xymovablewidget.h" 2 | #include 3 | 4 | XYMovableWidget::XYMovableWidget(QWidget *parent) 5 | : QWidget(parent) 6 | { 7 | mbLeftMousePressed = false; 8 | } 9 | 10 | XYMovableWidget::~XYMovableWidget() 11 | { 12 | 13 | } 14 | 15 | void XYMovableWidget::mousePressEvent(QMouseEvent *event) 16 | { 17 | if (event->button() == Qt::LeftButton) 18 | { 19 | mbLeftMousePressed = true; 20 | moLastPos = event->globalPos(); 21 | } 22 | QWidget::mousePressEvent(event); 23 | } 24 | 25 | void XYMovableWidget::mouseReleaseEvent(QMouseEvent *event) 26 | { 27 | if (event->button() == Qt::LeftButton) 28 | { 29 | mbLeftMousePressed = false; 30 | moLastPos = event->globalPos(); 31 | } 32 | QWidget::mouseReleaseEvent(event); 33 | } 34 | 35 | void XYMovableWidget::mouseMoveEvent(QMouseEvent *event) 36 | { 37 | if (mbLeftMousePressed && rect().contains(event->pos())) 38 | { 39 | QPoint lastpos = pos(); 40 | lastpos.setX( lastpos.x() + event->globalX() - moLastPos.x()); 41 | lastpos.setY( lastpos.y() + event->globalY() - moLastPos.y()); 42 | move(lastpos); 43 | moLastPos = event->globalPos(); 44 | } 45 | QWidget::mouseMoveEvent(event); 46 | } 47 | 48 | -------------------------------------------------------------------------------- /xymovablewidget.h: -------------------------------------------------------------------------------- 1 | #ifndef XYMOVABLEWIDGET_H 2 | #define XYMOVABLEWIDGET_H 3 | 4 | #include 5 | 6 | class XYMovableWidget : public QWidget 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit XYMovableWidget(QWidget *parent = 0); 11 | ~XYMovableWidget(); 12 | 13 | protected: 14 | void mousePressEvent(QMouseEvent *event); 15 | void mouseReleaseEvent(QMouseEvent *event); 16 | void mouseMoveEvent(QMouseEvent *event); 17 | 18 | protected: 19 | bool mbLeftMousePressed; 20 | QPoint moLastPos; 21 | 22 | }; 23 | 24 | #endif // XYMOVABLEWIDGET_H 25 | -------------------------------------------------------------------------------- /xypensettingwidget.cpp: -------------------------------------------------------------------------------- 1 | #include "xypensettingwidget.h" 2 | #include "xymovablegraphicsitem.h" 3 | 4 | XYPenSettingWidget *XYPenSettingWidget::getInstance() 5 | { 6 | static XYPenSettingWidget *instance = NULL; 7 | if (instance == NULL) 8 | { 9 | instance = new XYPenSettingWidget; 10 | } 11 | return instance; 12 | } 13 | 14 | XYPenSettingWidget::XYPenSettingWidget(QWidget *parent) 15 | : XYMovableWidget(parent), emitSignal(true) 16 | { 17 | this->setWindowFlags(Qt::FramelessWindowHint 18 | | Qt::WindowType_Mask); 19 | 20 | #define ADDITEM(instance, value) instance->addItem(#value, (int)value) 21 | int row = 0; 22 | QLabel *penColor = new QLabel(QStringLiteral("画笔颜色")); 23 | selectPenColor = new XYLabel(QColor("green")); 24 | connect(selectPenColor, SIGNAL(colorChanged(QColor)), this, SLOT(slotPenChanged())); 25 | QLabel *penStyle = new QLabel(QStringLiteral("画笔风格")); 26 | selectPenStyle = new QComboBox; 27 | ADDITEM(selectPenStyle, Qt::SolidLine); 28 | ADDITEM(selectPenStyle, Qt::DashLine); 29 | ADDITEM(selectPenStyle, Qt::DotLine); 30 | ADDITEM(selectPenStyle, Qt::DashDotLine); 31 | ADDITEM(selectPenStyle, Qt::DashDotDotLine); 32 | ADDITEM(selectPenStyle, Qt::NoPen); 33 | connect(selectPenStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(slotPenChanged())); 34 | QLabel *penOpacity = new QLabel(QStringLiteral("画笔透明度")); 35 | penOpacityBox = new QSlider; 36 | penOpacityBox->setOrientation(Qt::Horizontal); 37 | penOpacityBox->setMinimum(0); 38 | penOpacityBox->setMaximum(255); 39 | penOpacityBox->setValue(0); 40 | connect(penOpacityBox, SIGNAL(valueChanged(int)), this, SLOT(slotPenChanged())); 41 | QLabel *penWidth = new QLabel(QStringLiteral("画笔宽度")); 42 | widthBox = new QSlider; 43 | widthBox->setOrientation(Qt::Horizontal); 44 | widthBox->setMinimum(1); 45 | widthBox->setMaximum(50); 46 | widthBox->setValue(1); 47 | connect(widthBox, SIGNAL(valueChanged(int)), this, SLOT(slotPenChanged())); 48 | QGroupBox *penBox = new QGroupBox(QStringLiteral("画笔设置")); 49 | QGridLayout *penLayout = new QGridLayout(penBox); 50 | row = 0; 51 | penLayout->addWidget(penColor, row, 0); 52 | penLayout->addWidget(selectPenColor, row++, 1); 53 | penLayout->addWidget(penStyle, row, 0); 54 | penLayout->addWidget(selectPenStyle, row++, 1); 55 | penLayout->addWidget(penOpacity, row, 0); 56 | penLayout->addWidget(penOpacityBox, row++, 1); 57 | penLayout->addWidget(penWidth, row, 0); 58 | penLayout->addWidget(widthBox, row++, 1); 59 | 60 | QLabel *brushColor = new QLabel(QStringLiteral("画刷颜色")); 61 | selectBrushColor = new XYLabel(QColor("green")); 62 | connect(selectBrushColor, SIGNAL(colorChanged(QColor)), this, SLOT(slotBrushChanged())); 63 | QLabel *brushStyle = new QLabel(QStringLiteral("画刷风格")); 64 | selectBrushStyle = new QComboBox; 65 | ADDITEM(selectBrushStyle, Qt::SolidPattern); 66 | ADDITEM(selectBrushStyle, Qt::Dense1Pattern); 67 | ADDITEM(selectBrushStyle, Qt::HorPattern); 68 | ADDITEM(selectBrushStyle, Qt::VerPattern); 69 | ADDITEM(selectBrushStyle, Qt::CrossPattern); 70 | ADDITEM(selectBrushStyle, Qt::BDiagPattern); 71 | ADDITEM(selectBrushStyle, Qt::FDiagPattern); 72 | ADDITEM(selectBrushStyle, Qt::DiagCrossPattern); 73 | ADDITEM(selectBrushStyle, Qt::NoBrush); 74 | connect(selectBrushStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(slotBrushChanged())); 75 | QLabel *brushOpacity = new QLabel(QStringLiteral("画刷透明度")); 76 | brushOpacityBox = new QSlider; 77 | brushOpacityBox->setOrientation(Qt::Horizontal); 78 | brushOpacityBox->setMinimum(0); 79 | brushOpacityBox->setMaximum(255); 80 | brushOpacityBox->setValue(0); 81 | connect(brushOpacityBox, SIGNAL(valueChanged(int)), this, SLOT(slotBrushChanged())); 82 | QGroupBox *brushBox = new QGroupBox(QStringLiteral("画刷设置")); 83 | QGridLayout *brushLayout = new QGridLayout(brushBox); 84 | row = 0; 85 | brushLayout->addWidget(brushColor, row, 0); 86 | brushLayout->addWidget(selectBrushColor, row++, 1); 87 | brushLayout->addWidget(brushStyle, row, 0); 88 | brushLayout->addWidget(selectBrushStyle, row++, 1); 89 | brushLayout->addWidget(brushOpacity, row, 0); 90 | brushLayout->addWidget(brushOpacityBox, row++, 1); 91 | 92 | QLabel *fontFamily = new QLabel(QStringLiteral("字体")); 93 | selectFonts = new QFontComboBox; 94 | connect(selectFonts, SIGNAL(currentFontChanged(QFont)), this, SLOT(slotFontChanged())); 95 | QLabel *fontSize = new QLabel(QStringLiteral("字体大小")); 96 | sizeBox = new QSlider; 97 | sizeBox->setOrientation(Qt::Horizontal); 98 | sizeBox->setMinimum(1); 99 | sizeBox->setMaximum(100); 100 | sizeBox->setValue(15); 101 | connect(sizeBox, SIGNAL(valueChanged(int)), this, SLOT(slotFontChanged())); 102 | QGroupBox *fontBox = new QGroupBox(QStringLiteral("字体设置")); 103 | QGridLayout *fontLayout = new QGridLayout(fontBox); 104 | row = 0; 105 | fontLayout->addWidget(fontFamily, row, 0); 106 | fontLayout->addWidget(selectFonts, row++, 1); 107 | fontLayout->addWidget(fontSize, row, 0); 108 | fontLayout->addWidget(sizeBox, row++, 1); 109 | 110 | QVBoxLayout *mainlayout = new QVBoxLayout(this); 111 | mainlayout->addWidget(penBox); 112 | mainlayout->addWidget(brushBox); 113 | mainlayout->addWidget(fontBox); 114 | } 115 | 116 | XYPenSettingWidget::~XYPenSettingWidget() 117 | { 118 | 119 | } 120 | QPen XYPenSettingWidget::getMoPen() 121 | { 122 | QColor color = selectPenColor->getColor(); 123 | color.setAlpha(255 - penOpacityBox->value()); 124 | moPen.setColor(color); 125 | moPen.setStyle((Qt::PenStyle)selectPenStyle->currentData().toInt()); 126 | moPen.setWidth(widthBox->value()); 127 | return moPen; 128 | } 129 | 130 | void XYPenSettingWidget::setMoPen(const QPen &value) 131 | { 132 | moPen = value; 133 | QColor color = moPen.color(); 134 | selectPenColor->setColor(color); 135 | penOpacityBox->setValue(255 - color.alpha()); 136 | selectPenStyle->setCurrentIndex(selectPenStyle->findData((int)moPen.style())); 137 | widthBox->setValue(moPen.width()); 138 | } 139 | QFont XYPenSettingWidget::getMoFont() 140 | { 141 | moFont = selectFonts->currentFont(); 142 | moFont.setPixelSize(sizeBox->value()); 143 | return moFont; 144 | } 145 | 146 | void XYPenSettingWidget::setMoFont(const QFont &value) 147 | { 148 | moFont = value; 149 | selectFonts->setCurrentFont(moFont); 150 | sizeBox->setValue(moFont.pixelSize()); 151 | } 152 | QBrush XYPenSettingWidget::getMoBrush() 153 | { 154 | QColor color = selectBrushColor->getColor(); 155 | color.setAlpha(255 - brushOpacityBox->value()); 156 | moBrush.setStyle((Qt::BrushStyle)selectBrushStyle->currentData().toInt()); 157 | moBrush.setColor(color); 158 | return moBrush; 159 | } 160 | 161 | void XYPenSettingWidget::setMoBrush(const QBrush &value) 162 | { 163 | moBrush = value; 164 | QColor color = moBrush.color(); 165 | brushOpacityBox->setValue(255 - color.alpha()); 166 | selectBrushColor->setColor(color); 167 | selectBrushStyle->setCurrentIndex(selectBrushStyle->findData((int)moBrush.style())); 168 | } 169 | 170 | void XYPenSettingWidget::slotPenChanged() 171 | { 172 | getMoPen(); 173 | if (emitSignal) 174 | { 175 | emit penChanged(moPen); 176 | } 177 | } 178 | 179 | void XYPenSettingWidget::slotBrushChanged() 180 | { 181 | getMoBrush(); 182 | if (emitSignal) 183 | { 184 | emit brushChanged(moBrush); 185 | } 186 | } 187 | 188 | void XYPenSettingWidget::slotFontChanged() 189 | { 190 | getMoFont(); 191 | if (emitSignal) 192 | { 193 | emit fontChanged(moFont); 194 | } 195 | } 196 | 197 | void XYPenSettingWidget::initWithItem(QGraphicsItem *selectItem) 198 | { 199 | if (selectItem != NULL 200 | && (selectItem->type() == XYMovableGraphicsItem::XYSHAPE 201 | || selectItem->type() == XYMovableGraphicsItem::XYSHAPEMOVABLE 202 | || selectItem->type() == XYMovableGraphicsItem::XYTEXT)) 203 | { 204 | XYShapeGraphicsItem *item = (XYShapeGraphicsItem *)selectItem; 205 | emitSignal = false; 206 | setMoPen(item->getPaintPen()); 207 | setMoBrush(item->brush()); 208 | setMoFont(item->getFont()); 209 | emitSignal = true; 210 | } 211 | } 212 | 213 | void XYLabel::mslotSelectColor() 214 | { 215 | color = QColorDialog::getColor(); 216 | emit colorChanged(color); 217 | update(); 218 | } 219 | 220 | void XYLabel::paintEvent(QPaintEvent *event) 221 | { 222 | QPainter painter(this); 223 | painter.setPen(QColor(0, 0, 0, 0)); 224 | painter.setBrush(color); 225 | painter.drawRect(rect()); 226 | } 227 | 228 | void XYLabel::mouseReleaseEvent(QMouseEvent *event) 229 | { 230 | if (rect().contains(event->pos())) 231 | { 232 | emit selectColor(); 233 | } 234 | } 235 | XYLabel::XYLabel(const QColor &color, QWidget *parent) 236 | :QLabel(parent), color(color) 237 | { 238 | setMaximumHeight(25); 239 | connect(this, SIGNAL(selectColor()), this, SLOT(mslotSelectColor())); 240 | } 241 | 242 | QColor XYLabel::getColor() const 243 | { 244 | return color; 245 | } 246 | 247 | void XYLabel::setColor(const QColor &value) 248 | { 249 | color = value; 250 | update(); 251 | } 252 | 253 | QSize XYLabel::sizeHint() const 254 | { 255 | return QSize(50, 25); 256 | } 257 | 258 | -------------------------------------------------------------------------------- /xypensettingwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef XYPENSETTINGWIDGET_H 2 | #define XYPENSETTINGWIDGET_H 3 | 4 | #include "xymovablewidget.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | class XYLabel: public QLabel 18 | { 19 | Q_OBJECT 20 | public: 21 | XYLabel(const QColor &color = QColor(), QWidget *parent = 0); 22 | 23 | QColor getColor() const; 24 | void setColor(const QColor &value); 25 | QSize sizeHint() const; 26 | 27 | signals: 28 | void selectColor(); 29 | void colorChanged(const QColor &color); 30 | 31 | public slots: 32 | void mslotSelectColor(); 33 | 34 | protected: 35 | void paintEvent(QPaintEvent *event); 36 | void mouseReleaseEvent(QMouseEvent *event); 37 | 38 | private: 39 | QColor color; 40 | }; 41 | 42 | class XYPenSettingWidget : public XYMovableWidget 43 | { 44 | Q_OBJECT 45 | public: 46 | static XYPenSettingWidget *getInstance(); 47 | explicit XYPenSettingWidget(QWidget *parent = 0); 48 | ~XYPenSettingWidget(); 49 | 50 | QPen getMoPen(); 51 | void setMoPen(const QPen &value); 52 | 53 | QFont getMoFont(); 54 | void setMoFont(const QFont &value); 55 | 56 | QBrush getMoBrush(); 57 | void setMoBrush(const QBrush &value); 58 | 59 | signals: 60 | void penChanged(const QPen &pen); 61 | void brushChanged(const QBrush &brush); 62 | void fontChanged(const QFont &font); 63 | 64 | public slots: 65 | void slotPenChanged(); 66 | void slotBrushChanged(); 67 | void slotFontChanged(); 68 | void initWithItem(QGraphicsItem *selectItem); 69 | 70 | private: 71 | QPen moPen; 72 | QBrush moBrush; 73 | QFont moFont; 74 | 75 | XYLabel *selectPenColor; 76 | QComboBox *selectPenStyle; 77 | QSlider *penOpacityBox; 78 | QSlider *widthBox; 79 | 80 | XYLabel *selectBrushColor; 81 | QComboBox *selectBrushStyle; 82 | QSlider *brushOpacityBox; 83 | 84 | QFontComboBox *selectFonts; 85 | QSlider *sizeBox; 86 | 87 | bool emitSignal; 88 | 89 | }; 90 | 91 | #endif // XYPENSETTINGWIDGET_H 92 | --------------------------------------------------------------------------------