qt 6.5.1 original
67
examples/widgets/graphicsview/diagramscene/CMakeLists.txt
Normal file
@ -0,0 +1,67 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(diagramscene LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/graphicsview/diagramscene")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(diagramscene
|
||||
arrow.cpp arrow.h
|
||||
diagramitem.cpp diagramitem.h
|
||||
diagramscene.cpp diagramscene.h
|
||||
diagramtextitem.cpp diagramtextitem.h
|
||||
main.cpp
|
||||
mainwindow.cpp mainwindow.h
|
||||
)
|
||||
|
||||
set_target_properties(diagramscene PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(diagramscene PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
# Resources:
|
||||
set(diagramscene_resource_files
|
||||
"images/background1.png"
|
||||
"images/background2.png"
|
||||
"images/background3.png"
|
||||
"images/background4.png"
|
||||
"images/bold.png"
|
||||
"images/bringtofront.png"
|
||||
"images/delete.png"
|
||||
"images/floodfill.png"
|
||||
"images/italic.png"
|
||||
"images/linecolor.png"
|
||||
"images/linepointer.png"
|
||||
"images/pointer.png"
|
||||
"images/sendtoback.png"
|
||||
"images/textpointer.png"
|
||||
"images/underline.png"
|
||||
)
|
||||
|
||||
qt_add_resources(diagramscene "diagramscene"
|
||||
PREFIX
|
||||
"/"
|
||||
FILES
|
||||
${diagramscene_resource_files}
|
||||
)
|
||||
|
||||
install(TARGETS diagramscene
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
102
examples/widgets/graphicsview/diagramscene/arrow.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
|
||||
#include "arrow.h"
|
||||
#include "diagramitem.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
#include <QtMath>
|
||||
|
||||
//! [0]
|
||||
Arrow::Arrow(DiagramItem *startItem, DiagramItem *endItem, QGraphicsItem *parent)
|
||||
: QGraphicsLineItem(parent), myStartItem(startItem), myEndItem(endItem)
|
||||
{
|
||||
setFlag(QGraphicsItem::ItemIsSelectable, true);
|
||||
setPen(QPen(myColor, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
QRectF Arrow::boundingRect() const
|
||||
{
|
||||
qreal extra = (pen().width() + 20) / 2.0;
|
||||
|
||||
return QRectF(line().p1(), QSizeF(line().p2().x() - line().p1().x(),
|
||||
line().p2().y() - line().p1().y()))
|
||||
.normalized()
|
||||
.adjusted(-extra, -extra, extra, extra);
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
QPainterPath Arrow::shape() const
|
||||
{
|
||||
QPainterPath path = QGraphicsLineItem::shape();
|
||||
path.addPolygon(arrowHead);
|
||||
return path;
|
||||
}
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
void Arrow::updatePosition()
|
||||
{
|
||||
QLineF line(mapFromItem(myStartItem, 0, 0), mapFromItem(myEndItem, 0, 0));
|
||||
setLine(line);
|
||||
}
|
||||
//! [3]
|
||||
|
||||
//! [4]
|
||||
void Arrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
|
||||
QWidget *)
|
||||
{
|
||||
if (myStartItem->collidesWithItem(myEndItem))
|
||||
return;
|
||||
|
||||
QPen myPen = pen();
|
||||
myPen.setColor(myColor);
|
||||
qreal arrowSize = 20;
|
||||
painter->setPen(myPen);
|
||||
painter->setBrush(myColor);
|
||||
//! [4] //! [5]
|
||||
|
||||
QLineF centerLine(myStartItem->pos(), myEndItem->pos());
|
||||
QPolygonF endPolygon = myEndItem->polygon();
|
||||
QPointF p1 = endPolygon.first() + myEndItem->pos();
|
||||
QPointF intersectPoint;
|
||||
for (int i = 1; i < endPolygon.count(); ++i) {
|
||||
QPointF p2 = endPolygon.at(i) + myEndItem->pos();
|
||||
QLineF polyLine = QLineF(p1, p2);
|
||||
QLineF::IntersectionType intersectionType =
|
||||
polyLine.intersects(centerLine, &intersectPoint);
|
||||
if (intersectionType == QLineF::BoundedIntersection)
|
||||
break;
|
||||
p1 = p2;
|
||||
}
|
||||
|
||||
setLine(QLineF(intersectPoint, myStartItem->pos()));
|
||||
//! [5] //! [6]
|
||||
|
||||
double angle = std::atan2(-line().dy(), line().dx());
|
||||
|
||||
QPointF arrowP1 = line().p1() + QPointF(sin(angle + M_PI / 3) * arrowSize,
|
||||
cos(angle + M_PI / 3) * arrowSize);
|
||||
QPointF arrowP2 = line().p1() + QPointF(sin(angle + M_PI - M_PI / 3) * arrowSize,
|
||||
cos(angle + M_PI - M_PI / 3) * arrowSize);
|
||||
|
||||
arrowHead.clear();
|
||||
arrowHead << line().p1() << arrowP1 << arrowP2;
|
||||
//! [6] //! [7]
|
||||
painter->drawLine(line());
|
||||
painter->drawPolygon(arrowHead);
|
||||
if (isSelected()) {
|
||||
painter->setPen(QPen(myColor, 1, Qt::DashLine));
|
||||
QLineF myLine = line();
|
||||
myLine.translate(0, 4.0);
|
||||
painter->drawLine(myLine);
|
||||
myLine.translate(0,-8.0);
|
||||
painter->drawLine(myLine);
|
||||
}
|
||||
}
|
||||
//! [7]
|
41
examples/widgets/graphicsview/diagramscene/arrow.h
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef ARROW_H
|
||||
#define ARROW_H
|
||||
|
||||
#include <QGraphicsLineItem>
|
||||
|
||||
class DiagramItem;
|
||||
|
||||
//! [0]
|
||||
class Arrow : public QGraphicsLineItem
|
||||
{
|
||||
public:
|
||||
enum { Type = UserType + 4 };
|
||||
|
||||
Arrow(DiagramItem *startItem, DiagramItem *endItem,
|
||||
QGraphicsItem *parent = nullptr);
|
||||
|
||||
int type() const override { return Type; }
|
||||
QRectF boundingRect() const override;
|
||||
QPainterPath shape() const override;
|
||||
void setColor(const QColor &color) { myColor = color; }
|
||||
DiagramItem *startItem() const { return myStartItem; }
|
||||
DiagramItem *endItem() const { return myEndItem; }
|
||||
|
||||
void updatePosition();
|
||||
|
||||
protected:
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
QWidget *widget = nullptr) override;
|
||||
|
||||
private:
|
||||
DiagramItem *myStartItem;
|
||||
DiagramItem *myEndItem;
|
||||
QPolygonF arrowHead;
|
||||
QColor myColor = Qt::black;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif // ARROW_H
|
114
examples/widgets/graphicsview/diagramscene/diagramitem.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "diagramitem.h"
|
||||
#include "arrow.h"
|
||||
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneContextMenuEvent>
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
|
||||
//! [0]
|
||||
DiagramItem::DiagramItem(DiagramType diagramType, QMenu *contextMenu,
|
||||
QGraphicsItem *parent)
|
||||
: QGraphicsPolygonItem(parent), myDiagramType(diagramType)
|
||||
, myContextMenu(contextMenu)
|
||||
{
|
||||
QPainterPath path;
|
||||
switch (myDiagramType) {
|
||||
case StartEnd:
|
||||
path.moveTo(200, 50);
|
||||
path.arcTo(150, 0, 50, 50, 0, 90);
|
||||
path.arcTo(50, 0, 50, 50, 90, 90);
|
||||
path.arcTo(50, 50, 50, 50, 180, 90);
|
||||
path.arcTo(150, 50, 50, 50, 270, 90);
|
||||
path.lineTo(200, 25);
|
||||
myPolygon = path.toFillPolygon();
|
||||
break;
|
||||
case Conditional:
|
||||
myPolygon << QPointF(-100, 0) << QPointF(0, 100)
|
||||
<< QPointF(100, 0) << QPointF(0, -100)
|
||||
<< QPointF(-100, 0);
|
||||
break;
|
||||
case Step:
|
||||
myPolygon << QPointF(-100, -100) << QPointF(100, -100)
|
||||
<< QPointF(100, 100) << QPointF(-100, 100)
|
||||
<< QPointF(-100, -100);
|
||||
break;
|
||||
default:
|
||||
myPolygon << QPointF(-120, -80) << QPointF(-70, 80)
|
||||
<< QPointF(120, 80) << QPointF(70, -80)
|
||||
<< QPointF(-120, -80);
|
||||
break;
|
||||
}
|
||||
setPolygon(myPolygon);
|
||||
setFlag(QGraphicsItem::ItemIsMovable, true);
|
||||
setFlag(QGraphicsItem::ItemIsSelectable, true);
|
||||
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
void DiagramItem::removeArrow(Arrow *arrow)
|
||||
{
|
||||
arrows.removeAll(arrow);
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
void DiagramItem::removeArrows()
|
||||
{
|
||||
// need a copy here since removeArrow() will
|
||||
// modify the arrows container
|
||||
const auto arrowsCopy = arrows;
|
||||
for (Arrow *arrow : arrowsCopy) {
|
||||
arrow->startItem()->removeArrow(arrow);
|
||||
arrow->endItem()->removeArrow(arrow);
|
||||
scene()->removeItem(arrow);
|
||||
delete arrow;
|
||||
}
|
||||
}
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
void DiagramItem::addArrow(Arrow *arrow)
|
||||
{
|
||||
arrows.append(arrow);
|
||||
}
|
||||
//! [3]
|
||||
|
||||
//! [4]
|
||||
QPixmap DiagramItem::image() const
|
||||
{
|
||||
QPixmap pixmap(250, 250);
|
||||
pixmap.fill(Qt::transparent);
|
||||
QPainter painter(&pixmap);
|
||||
painter.setPen(QPen(Qt::black, 8));
|
||||
painter.translate(125, 125);
|
||||
painter.drawPolyline(myPolygon);
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
void DiagramItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
|
||||
{
|
||||
scene()->clearSelection();
|
||||
setSelected(true);
|
||||
myContextMenu->popup(event->screenPos());
|
||||
}
|
||||
//! [5]
|
||||
|
||||
//! [6]
|
||||
QVariant DiagramItem::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
if (change == QGraphicsItem::ItemPositionChange) {
|
||||
for (Arrow *arrow : std::as_const(arrows))
|
||||
arrow->updatePosition();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
//! [6]
|
48
examples/widgets/graphicsview/diagramscene/diagramitem.h
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef DIAGRAMITEM_H
|
||||
#define DIAGRAMITEM_H
|
||||
|
||||
#include <QGraphicsPixmapItem>
|
||||
#include <QList>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QPixmap;
|
||||
class QGraphicsSceneContextMenuEvent;
|
||||
class QMenu;
|
||||
class QPolygonF;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class Arrow;
|
||||
|
||||
//! [0]
|
||||
class DiagramItem : public QGraphicsPolygonItem
|
||||
{
|
||||
public:
|
||||
enum { Type = UserType + 15 };
|
||||
enum DiagramType { Step, Conditional, StartEnd, Io };
|
||||
|
||||
DiagramItem(DiagramType diagramType, QMenu *contextMenu, QGraphicsItem *parent = nullptr);
|
||||
|
||||
void removeArrow(Arrow *arrow);
|
||||
void removeArrows();
|
||||
DiagramType diagramType() const { return myDiagramType; }
|
||||
QPolygonF polygon() const { return myPolygon; }
|
||||
void addArrow(Arrow *arrow);
|
||||
QPixmap image() const;
|
||||
int type() const override { return Type; }
|
||||
|
||||
protected:
|
||||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
|
||||
|
||||
private:
|
||||
DiagramType myDiagramType;
|
||||
QPolygonF myPolygon;
|
||||
QMenu *myContextMenu;
|
||||
QList<Arrow *> arrows;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif // DIAGRAMITEM_H
|
196
examples/widgets/graphicsview/diagramscene/diagramscene.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "diagramscene.h"
|
||||
#include "arrow.h"
|
||||
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QTextCursor>
|
||||
|
||||
//! [0]
|
||||
DiagramScene::DiagramScene(QMenu *itemMenu, QObject *parent)
|
||||
: QGraphicsScene(parent)
|
||||
{
|
||||
myItemMenu = itemMenu;
|
||||
myMode = MoveItem;
|
||||
myItemType = DiagramItem::Step;
|
||||
line = nullptr;
|
||||
textItem = nullptr;
|
||||
myItemColor = Qt::white;
|
||||
myTextColor = Qt::black;
|
||||
myLineColor = Qt::black;
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
void DiagramScene::setLineColor(const QColor &color)
|
||||
{
|
||||
myLineColor = color;
|
||||
if (isItemChange(Arrow::Type)) {
|
||||
Arrow *item = qgraphicsitem_cast<Arrow *>(selectedItems().first());
|
||||
item->setColor(myLineColor);
|
||||
update();
|
||||
}
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
void DiagramScene::setTextColor(const QColor &color)
|
||||
{
|
||||
myTextColor = color;
|
||||
if (isItemChange(DiagramTextItem::Type)) {
|
||||
DiagramTextItem *item = qgraphicsitem_cast<DiagramTextItem *>(selectedItems().first());
|
||||
item->setDefaultTextColor(myTextColor);
|
||||
}
|
||||
}
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
void DiagramScene::setItemColor(const QColor &color)
|
||||
{
|
||||
myItemColor = color;
|
||||
if (isItemChange(DiagramItem::Type)) {
|
||||
DiagramItem *item = qgraphicsitem_cast<DiagramItem *>(selectedItems().first());
|
||||
item->setBrush(myItemColor);
|
||||
}
|
||||
}
|
||||
//! [3]
|
||||
|
||||
//! [4]
|
||||
void DiagramScene::setFont(const QFont &font)
|
||||
{
|
||||
myFont = font;
|
||||
|
||||
if (isItemChange(DiagramTextItem::Type)) {
|
||||
QGraphicsTextItem *item = qgraphicsitem_cast<DiagramTextItem *>(selectedItems().first());
|
||||
//At this point the selection can change so the first selected item might not be a DiagramTextItem
|
||||
if (item)
|
||||
item->setFont(myFont);
|
||||
}
|
||||
}
|
||||
//! [4]
|
||||
|
||||
void DiagramScene::setMode(Mode mode)
|
||||
{
|
||||
myMode = mode;
|
||||
}
|
||||
|
||||
void DiagramScene::setItemType(DiagramItem::DiagramType type)
|
||||
{
|
||||
myItemType = type;
|
||||
}
|
||||
|
||||
//! [5]
|
||||
void DiagramScene::editorLostFocus(DiagramTextItem *item)
|
||||
{
|
||||
QTextCursor cursor = item->textCursor();
|
||||
cursor.clearSelection();
|
||||
item->setTextCursor(cursor);
|
||||
|
||||
if (item->toPlainText().isEmpty()) {
|
||||
removeItem(item);
|
||||
item->deleteLater();
|
||||
}
|
||||
}
|
||||
//! [5]
|
||||
|
||||
//! [6]
|
||||
void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||
{
|
||||
if (mouseEvent->button() != Qt::LeftButton)
|
||||
return;
|
||||
|
||||
DiagramItem *item;
|
||||
switch (myMode) {
|
||||
case InsertItem:
|
||||
item = new DiagramItem(myItemType, myItemMenu);
|
||||
item->setBrush(myItemColor);
|
||||
addItem(item);
|
||||
item->setPos(mouseEvent->scenePos());
|
||||
emit itemInserted(item);
|
||||
break;
|
||||
//! [6] //! [7]
|
||||
case InsertLine:
|
||||
line = new QGraphicsLineItem(QLineF(mouseEvent->scenePos(),
|
||||
mouseEvent->scenePos()));
|
||||
line->setPen(QPen(myLineColor, 2));
|
||||
addItem(line);
|
||||
break;
|
||||
//! [7] //! [8]
|
||||
case InsertText:
|
||||
textItem = new DiagramTextItem();
|
||||
textItem->setFont(myFont);
|
||||
textItem->setTextInteractionFlags(Qt::TextEditorInteraction);
|
||||
textItem->setZValue(1000.0);
|
||||
connect(textItem, &DiagramTextItem::lostFocus,
|
||||
this, &DiagramScene::editorLostFocus);
|
||||
connect(textItem, &DiagramTextItem::selectedChange,
|
||||
this, &DiagramScene::itemSelected);
|
||||
addItem(textItem);
|
||||
textItem->setDefaultTextColor(myTextColor);
|
||||
textItem->setPos(mouseEvent->scenePos());
|
||||
emit textInserted(textItem);
|
||||
//! [8] //! [9]
|
||||
default:
|
||||
;
|
||||
}
|
||||
QGraphicsScene::mousePressEvent(mouseEvent);
|
||||
}
|
||||
//! [9]
|
||||
|
||||
//! [10]
|
||||
void DiagramScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||
{
|
||||
if (myMode == InsertLine && line != nullptr) {
|
||||
QLineF newLine(line->line().p1(), mouseEvent->scenePos());
|
||||
line->setLine(newLine);
|
||||
} else if (myMode == MoveItem) {
|
||||
QGraphicsScene::mouseMoveEvent(mouseEvent);
|
||||
}
|
||||
}
|
||||
//! [10]
|
||||
|
||||
//! [11]
|
||||
void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||
{
|
||||
if (line != nullptr && myMode == InsertLine) {
|
||||
QList<QGraphicsItem *> startItems = items(line->line().p1());
|
||||
if (startItems.count() && startItems.first() == line)
|
||||
startItems.removeFirst();
|
||||
QList<QGraphicsItem *> endItems = items(line->line().p2());
|
||||
if (endItems.count() && endItems.first() == line)
|
||||
endItems.removeFirst();
|
||||
|
||||
removeItem(line);
|
||||
delete line;
|
||||
//! [11] //! [12]
|
||||
|
||||
if (startItems.count() > 0 && endItems.count() > 0 &&
|
||||
startItems.first()->type() == DiagramItem::Type &&
|
||||
endItems.first()->type() == DiagramItem::Type &&
|
||||
startItems.first() != endItems.first()) {
|
||||
DiagramItem *startItem = qgraphicsitem_cast<DiagramItem *>(startItems.first());
|
||||
DiagramItem *endItem = qgraphicsitem_cast<DiagramItem *>(endItems.first());
|
||||
Arrow *arrow = new Arrow(startItem, endItem);
|
||||
arrow->setColor(myLineColor);
|
||||
startItem->addArrow(arrow);
|
||||
endItem->addArrow(arrow);
|
||||
arrow->setZValue(-1000.0);
|
||||
addItem(arrow);
|
||||
arrow->updatePosition();
|
||||
}
|
||||
}
|
||||
//! [12] //! [13]
|
||||
line = nullptr;
|
||||
QGraphicsScene::mouseReleaseEvent(mouseEvent);
|
||||
}
|
||||
//! [13]
|
||||
|
||||
//! [14]
|
||||
bool DiagramScene::isItemChange(int type) const
|
||||
{
|
||||
const QList<QGraphicsItem *> items = selectedItems();
|
||||
const auto cb = [type](const QGraphicsItem *item) { return item->type() == type; };
|
||||
return std::find_if(items.begin(), items.end(), cb) != items.end();
|
||||
}
|
||||
//! [14]
|
72
examples/widgets/graphicsview/diagramscene/diagramscene.h
Normal file
@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef DIAGRAMSCENE_H
|
||||
#define DIAGRAMSCENE_H
|
||||
|
||||
#include "diagramitem.h"
|
||||
#include "diagramtextitem.h"
|
||||
|
||||
#include <QGraphicsScene>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QGraphicsSceneMouseEvent;
|
||||
class QMenu;
|
||||
class QPointF;
|
||||
class QGraphicsLineItem;
|
||||
class QFont;
|
||||
class QGraphicsTextItem;
|
||||
class QColor;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
//! [0]
|
||||
class DiagramScene : public QGraphicsScene
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Mode { InsertItem, InsertLine, InsertText, MoveItem };
|
||||
|
||||
explicit DiagramScene(QMenu *itemMenu, QObject *parent = nullptr);
|
||||
QFont font() const { return myFont; }
|
||||
QColor textColor() const { return myTextColor; }
|
||||
QColor itemColor() const { return myItemColor; }
|
||||
QColor lineColor() const { return myLineColor; }
|
||||
void setLineColor(const QColor &color);
|
||||
void setTextColor(const QColor &color);
|
||||
void setItemColor(const QColor &color);
|
||||
void setFont(const QFont &font);
|
||||
|
||||
public slots:
|
||||
void setMode(Mode mode);
|
||||
void setItemType(DiagramItem::DiagramType type);
|
||||
void editorLostFocus(DiagramTextItem *item);
|
||||
|
||||
signals:
|
||||
void itemInserted(DiagramItem *item);
|
||||
void textInserted(QGraphicsTextItem *item);
|
||||
void itemSelected(QGraphicsItem *item);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
|
||||
|
||||
private:
|
||||
bool isItemChange(int type) const;
|
||||
|
||||
DiagramItem::DiagramType myItemType;
|
||||
QMenu *myItemMenu;
|
||||
Mode myMode;
|
||||
bool leftButtonDown;
|
||||
QPointF startPoint;
|
||||
QGraphicsLineItem *line;
|
||||
QFont myFont;
|
||||
DiagramTextItem *textItem;
|
||||
QColor myTextColor;
|
||||
QColor myItemColor;
|
||||
QColor myLineColor;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif // DIAGRAMSCENE_H
|
20
examples/widgets/graphicsview/diagramscene/diagramscene.pro
Normal file
@ -0,0 +1,20 @@
|
||||
QT += widgets
|
||||
requires(qtConfig(fontcombobox))
|
||||
|
||||
HEADERS = mainwindow.h \
|
||||
diagramitem.h \
|
||||
diagramscene.h \
|
||||
arrow.h \
|
||||
diagramtextitem.h
|
||||
SOURCES = mainwindow.cpp \
|
||||
diagramitem.cpp \
|
||||
main.cpp \
|
||||
arrow.cpp \
|
||||
diagramtextitem.cpp \
|
||||
diagramscene.cpp
|
||||
RESOURCES = diagramscene.qrc
|
||||
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/graphicsview/diagramscene
|
||||
INSTALLS += target
|
20
examples/widgets/graphicsview/diagramscene/diagramscene.qrc
Normal file
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>images/pointer.png</file>
|
||||
<file>images/linepointer.png</file>
|
||||
<file>images/textpointer.png</file>
|
||||
<file>images/bold.png</file>
|
||||
<file>images/italic.png</file>
|
||||
<file>images/underline.png</file>
|
||||
<file>images/floodfill.png</file>
|
||||
<file>images/bringtofront.png</file>
|
||||
<file>images/delete.png</file>
|
||||
<file>images/sendtoback.png</file>
|
||||
<file>images/linecolor.png</file>
|
||||
<file>images/background1.png</file>
|
||||
<file>images/background2.png</file>
|
||||
<file>images/background3.png</file>
|
||||
<file>images/background4.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "diagramtextitem.h"
|
||||
#include "diagramscene.h"
|
||||
|
||||
//! [0]
|
||||
DiagramTextItem::DiagramTextItem(QGraphicsItem *parent)
|
||||
: QGraphicsTextItem(parent)
|
||||
{
|
||||
setFlag(QGraphicsItem::ItemIsMovable);
|
||||
setFlag(QGraphicsItem::ItemIsSelectable);
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
QVariant DiagramTextItem::itemChange(GraphicsItemChange change,
|
||||
const QVariant &value)
|
||||
{
|
||||
if (change == QGraphicsItem::ItemSelectedHasChanged)
|
||||
emit selectedChange(this);
|
||||
return value;
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
void DiagramTextItem::focusOutEvent(QFocusEvent *event)
|
||||
{
|
||||
setTextInteractionFlags(Qt::NoTextInteraction);
|
||||
emit lostFocus(this);
|
||||
QGraphicsTextItem::focusOutEvent(event);
|
||||
}
|
||||
//! [2]
|
||||
|
||||
//! [5]
|
||||
void DiagramTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (textInteractionFlags() == Qt::NoTextInteraction)
|
||||
setTextInteractionFlags(Qt::TextEditorInteraction);
|
||||
QGraphicsTextItem::mouseDoubleClickEvent(event);
|
||||
}
|
||||
//! [5]
|
36
examples/widgets/graphicsview/diagramscene/diagramtextitem.h
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef DIAGRAMTEXTITEM_H
|
||||
#define DIAGRAMTEXTITEM_H
|
||||
|
||||
#include <QGraphicsTextItem>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QGraphicsSceneMouseEvent;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
//! [0]
|
||||
class DiagramTextItem : public QGraphicsTextItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum { Type = UserType + 3 };
|
||||
|
||||
DiagramTextItem(QGraphicsItem *parent = nullptr);
|
||||
|
||||
int type() const override { return Type; }
|
||||
|
||||
signals:
|
||||
void lostFocus(DiagramTextItem *item);
|
||||
void selectedChange(QGraphicsItem *item);
|
||||
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
|
||||
void focusOutEvent(QFocusEvent *event) override;
|
||||
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif // DIAGRAMTEXTITEM_H
|
After Width: | Height: | Size: 112 B |
After Width: | Height: | Size: 114 B |
After Width: | Height: | Size: 116 B |
After Width: | Height: | Size: 96 B |
BIN
examples/widgets/graphicsview/diagramscene/images/bold.png
Normal file
After Width: | Height: | Size: 353 B |
After Width: | Height: | Size: 293 B |
BIN
examples/widgets/graphicsview/diagramscene/images/delete.png
Normal file
After Width: | Height: | Size: 831 B |
BIN
examples/widgets/graphicsview/diagramscene/images/floodfill.png
Normal file
After Width: | Height: | Size: 282 B |
BIN
examples/widgets/graphicsview/diagramscene/images/italic.png
Normal file
After Width: | Height: | Size: 299 B |
BIN
examples/widgets/graphicsview/diagramscene/images/linecolor.png
Normal file
After Width: | Height: | Size: 145 B |
After Width: | Height: | Size: 141 B |
BIN
examples/widgets/graphicsview/diagramscene/images/pointer.png
Normal file
After Width: | Height: | Size: 230 B |
BIN
examples/widgets/graphicsview/diagramscene/images/sendtoback.png
Normal file
After Width: | Height: | Size: 318 B |
After Width: | Height: | Size: 893 B |
BIN
examples/widgets/graphicsview/diagramscene/images/underline.png
Normal file
After Width: | Height: | Size: 307 B |
18
examples/widgets/graphicsview/diagramscene/main.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argv, char *args[])
|
||||
{
|
||||
Q_INIT_RESOURCE(diagramscene);
|
||||
|
||||
QApplication app(argv, args);
|
||||
MainWindow mainWindow;
|
||||
mainWindow.setGeometry(100, 100, 800, 500);
|
||||
mainWindow.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
599
examples/widgets/graphicsview/diagramscene/mainwindow.cpp
Normal file
@ -0,0 +1,599 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "arrow.h"
|
||||
#include "diagramitem.h"
|
||||
#include "diagramscene.h"
|
||||
#include "diagramtextitem.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
const int InsertTextButton = 10;
|
||||
|
||||
//! [0]
|
||||
MainWindow::MainWindow()
|
||||
{
|
||||
createActions();
|
||||
createToolBox();
|
||||
createMenus();
|
||||
|
||||
scene = new DiagramScene(itemMenu, this);
|
||||
scene->setSceneRect(QRectF(0, 0, 5000, 5000));
|
||||
connect(scene, &DiagramScene::itemInserted,
|
||||
this, &MainWindow::itemInserted);
|
||||
connect(scene, &DiagramScene::textInserted,
|
||||
this, &MainWindow::textInserted);
|
||||
connect(scene, &DiagramScene::itemSelected,
|
||||
this, &MainWindow::itemSelected);
|
||||
createToolbars();
|
||||
|
||||
QHBoxLayout *layout = new QHBoxLayout;
|
||||
layout->addWidget(toolBox);
|
||||
view = new QGraphicsView(scene);
|
||||
layout->addWidget(view);
|
||||
|
||||
QWidget *widget = new QWidget;
|
||||
widget->setLayout(layout);
|
||||
|
||||
setCentralWidget(widget);
|
||||
setWindowTitle(tr("Diagramscene"));
|
||||
setUnifiedTitleAndToolBarOnMac(true);
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
void MainWindow::backgroundButtonGroupClicked(QAbstractButton *button)
|
||||
{
|
||||
const QList<QAbstractButton *> buttons = backgroundButtonGroup->buttons();
|
||||
for (QAbstractButton *myButton : buttons) {
|
||||
if (myButton != button)
|
||||
button->setChecked(false);
|
||||
}
|
||||
QString text = button->text();
|
||||
if (text == tr("Blue Grid"))
|
||||
scene->setBackgroundBrush(QPixmap(":/images/background1.png"));
|
||||
else if (text == tr("White Grid"))
|
||||
scene->setBackgroundBrush(QPixmap(":/images/background2.png"));
|
||||
else if (text == tr("Gray Grid"))
|
||||
scene->setBackgroundBrush(QPixmap(":/images/background3.png"));
|
||||
else
|
||||
scene->setBackgroundBrush(QPixmap(":/images/background4.png"));
|
||||
|
||||
scene->update();
|
||||
view->update();
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
void MainWindow::buttonGroupClicked(QAbstractButton *button)
|
||||
{
|
||||
const QList<QAbstractButton *> buttons = buttonGroup->buttons();
|
||||
for (QAbstractButton *myButton : buttons) {
|
||||
if (myButton != button)
|
||||
button->setChecked(false);
|
||||
}
|
||||
const int id = buttonGroup->id(button);
|
||||
if (id == InsertTextButton) {
|
||||
scene->setMode(DiagramScene::InsertText);
|
||||
} else {
|
||||
scene->setItemType(DiagramItem::DiagramType(id));
|
||||
scene->setMode(DiagramScene::InsertItem);
|
||||
}
|
||||
}
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
void MainWindow::deleteItem()
|
||||
{
|
||||
QList<QGraphicsItem *> selectedItems = scene->selectedItems();
|
||||
for (QGraphicsItem *item : std::as_const(selectedItems)) {
|
||||
if (item->type() == Arrow::Type) {
|
||||
scene->removeItem(item);
|
||||
Arrow *arrow = qgraphicsitem_cast<Arrow *>(item);
|
||||
arrow->startItem()->removeArrow(arrow);
|
||||
arrow->endItem()->removeArrow(arrow);
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
selectedItems = scene->selectedItems();
|
||||
for (QGraphicsItem *item : std::as_const(selectedItems)) {
|
||||
if (item->type() == DiagramItem::Type)
|
||||
qgraphicsitem_cast<DiagramItem *>(item)->removeArrows();
|
||||
scene->removeItem(item);
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
//! [3]
|
||||
|
||||
//! [4]
|
||||
void MainWindow::pointerGroupClicked()
|
||||
{
|
||||
scene->setMode(DiagramScene::Mode(pointerTypeGroup->checkedId()));
|
||||
}
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
void MainWindow::bringToFront()
|
||||
{
|
||||
if (scene->selectedItems().isEmpty())
|
||||
return;
|
||||
|
||||
QGraphicsItem *selectedItem = scene->selectedItems().first();
|
||||
const QList<QGraphicsItem *> overlapItems = selectedItem->collidingItems();
|
||||
|
||||
qreal zValue = 0;
|
||||
for (const QGraphicsItem *item : overlapItems) {
|
||||
if (item->zValue() >= zValue && item->type() == DiagramItem::Type)
|
||||
zValue = item->zValue() + 0.1;
|
||||
}
|
||||
selectedItem->setZValue(zValue);
|
||||
}
|
||||
//! [5]
|
||||
|
||||
//! [6]
|
||||
void MainWindow::sendToBack()
|
||||
{
|
||||
if (scene->selectedItems().isEmpty())
|
||||
return;
|
||||
|
||||
QGraphicsItem *selectedItem = scene->selectedItems().first();
|
||||
const QList<QGraphicsItem *> overlapItems = selectedItem->collidingItems();
|
||||
|
||||
qreal zValue = 0;
|
||||
for (const QGraphicsItem *item : overlapItems) {
|
||||
if (item->zValue() <= zValue && item->type() == DiagramItem::Type)
|
||||
zValue = item->zValue() - 0.1;
|
||||
}
|
||||
selectedItem->setZValue(zValue);
|
||||
}
|
||||
//! [6]
|
||||
|
||||
//! [7]
|
||||
void MainWindow::itemInserted(DiagramItem *item)
|
||||
{
|
||||
pointerTypeGroup->button(int(DiagramScene::MoveItem))->setChecked(true);
|
||||
scene->setMode(DiagramScene::Mode(pointerTypeGroup->checkedId()));
|
||||
buttonGroup->button(int(item->diagramType()))->setChecked(false);
|
||||
}
|
||||
//! [7]
|
||||
|
||||
//! [8]
|
||||
void MainWindow::textInserted(QGraphicsTextItem *)
|
||||
{
|
||||
buttonGroup->button(InsertTextButton)->setChecked(false);
|
||||
scene->setMode(DiagramScene::Mode(pointerTypeGroup->checkedId()));
|
||||
}
|
||||
//! [8]
|
||||
|
||||
//! [9]
|
||||
void MainWindow::currentFontChanged(const QFont &)
|
||||
{
|
||||
handleFontChange();
|
||||
}
|
||||
//! [9]
|
||||
|
||||
//! [10]
|
||||
void MainWindow::fontSizeChanged(const QString &)
|
||||
{
|
||||
handleFontChange();
|
||||
}
|
||||
//! [10]
|
||||
|
||||
//! [11]
|
||||
void MainWindow::sceneScaleChanged(const QString &scale)
|
||||
{
|
||||
double newScale = scale.left(scale.indexOf(tr("%"))).toDouble() / 100.0;
|
||||
QTransform oldMatrix = view->transform();
|
||||
view->resetTransform();
|
||||
view->translate(oldMatrix.dx(), oldMatrix.dy());
|
||||
view->scale(newScale, newScale);
|
||||
}
|
||||
//! [11]
|
||||
|
||||
//! [12]
|
||||
void MainWindow::textColorChanged()
|
||||
{
|
||||
textAction = qobject_cast<QAction *>(sender());
|
||||
fontColorToolButton->setIcon(createColorToolButtonIcon(
|
||||
":/images/textpointer.png",
|
||||
qvariant_cast<QColor>(textAction->data())));
|
||||
textButtonTriggered();
|
||||
}
|
||||
//! [12]
|
||||
|
||||
//! [13]
|
||||
void MainWindow::itemColorChanged()
|
||||
{
|
||||
fillAction = qobject_cast<QAction *>(sender());
|
||||
fillColorToolButton->setIcon(createColorToolButtonIcon(
|
||||
":/images/floodfill.png",
|
||||
qvariant_cast<QColor>(fillAction->data())));
|
||||
fillButtonTriggered();
|
||||
}
|
||||
//! [13]
|
||||
|
||||
//! [14]
|
||||
void MainWindow::lineColorChanged()
|
||||
{
|
||||
lineAction = qobject_cast<QAction *>(sender());
|
||||
lineColorToolButton->setIcon(createColorToolButtonIcon(
|
||||
":/images/linecolor.png",
|
||||
qvariant_cast<QColor>(lineAction->data())));
|
||||
lineButtonTriggered();
|
||||
}
|
||||
//! [14]
|
||||
|
||||
//! [15]
|
||||
void MainWindow::textButtonTriggered()
|
||||
{
|
||||
scene->setTextColor(qvariant_cast<QColor>(textAction->data()));
|
||||
}
|
||||
//! [15]
|
||||
|
||||
//! [16]
|
||||
void MainWindow::fillButtonTriggered()
|
||||
{
|
||||
scene->setItemColor(qvariant_cast<QColor>(fillAction->data()));
|
||||
}
|
||||
//! [16]
|
||||
|
||||
//! [17]
|
||||
void MainWindow::lineButtonTriggered()
|
||||
{
|
||||
scene->setLineColor(qvariant_cast<QColor>(lineAction->data()));
|
||||
}
|
||||
//! [17]
|
||||
|
||||
//! [18]
|
||||
void MainWindow::handleFontChange()
|
||||
{
|
||||
QFont font = fontCombo->currentFont();
|
||||
font.setPointSize(fontSizeCombo->currentText().toInt());
|
||||
font.setWeight(boldAction->isChecked() ? QFont::Bold : QFont::Normal);
|
||||
font.setItalic(italicAction->isChecked());
|
||||
font.setUnderline(underlineAction->isChecked());
|
||||
|
||||
scene->setFont(font);
|
||||
}
|
||||
//! [18]
|
||||
|
||||
//! [19]
|
||||
void MainWindow::itemSelected(QGraphicsItem *item)
|
||||
{
|
||||
DiagramTextItem *textItem =
|
||||
qgraphicsitem_cast<DiagramTextItem *>(item);
|
||||
|
||||
QFont font = textItem->font();
|
||||
fontCombo->setCurrentFont(font);
|
||||
fontSizeCombo->setEditText(QString().setNum(font.pointSize()));
|
||||
boldAction->setChecked(font.weight() == QFont::Bold);
|
||||
italicAction->setChecked(font.italic());
|
||||
underlineAction->setChecked(font.underline());
|
||||
}
|
||||
//! [19]
|
||||
|
||||
//! [20]
|
||||
void MainWindow::about()
|
||||
{
|
||||
QMessageBox::about(this, tr("About Diagram Scene"),
|
||||
tr("The <b>Diagram Scene</b> example shows "
|
||||
"use of the graphics framework."));
|
||||
}
|
||||
//! [20]
|
||||
|
||||
//! [21]
|
||||
void MainWindow::createToolBox()
|
||||
{
|
||||
buttonGroup = new QButtonGroup(this);
|
||||
buttonGroup->setExclusive(false);
|
||||
connect(buttonGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked),
|
||||
this, &MainWindow::buttonGroupClicked);
|
||||
QGridLayout *layout = new QGridLayout;
|
||||
layout->addWidget(createCellWidget(tr("Conditional"), DiagramItem::Conditional), 0, 0);
|
||||
layout->addWidget(createCellWidget(tr("Process"), DiagramItem::Step),0, 1);
|
||||
layout->addWidget(createCellWidget(tr("Input/Output"), DiagramItem::Io), 1, 0);
|
||||
//! [21]
|
||||
|
||||
QToolButton *textButton = new QToolButton;
|
||||
textButton->setCheckable(true);
|
||||
buttonGroup->addButton(textButton, InsertTextButton);
|
||||
textButton->setIcon(QIcon(QPixmap(":/images/textpointer.png")));
|
||||
textButton->setIconSize(QSize(50, 50));
|
||||
QGridLayout *textLayout = new QGridLayout;
|
||||
textLayout->addWidget(textButton, 0, 0, Qt::AlignHCenter);
|
||||
textLayout->addWidget(new QLabel(tr("Text")), 1, 0, Qt::AlignCenter);
|
||||
QWidget *textWidget = new QWidget;
|
||||
textWidget->setLayout(textLayout);
|
||||
layout->addWidget(textWidget, 1, 1);
|
||||
|
||||
layout->setRowStretch(3, 10);
|
||||
layout->setColumnStretch(2, 10);
|
||||
|
||||
QWidget *itemWidget = new QWidget;
|
||||
itemWidget->setLayout(layout);
|
||||
|
||||
backgroundButtonGroup = new QButtonGroup(this);
|
||||
connect(backgroundButtonGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked),
|
||||
this, &MainWindow::backgroundButtonGroupClicked);
|
||||
|
||||
QGridLayout *backgroundLayout = new QGridLayout;
|
||||
backgroundLayout->addWidget(createBackgroundCellWidget(tr("Blue Grid"),
|
||||
":/images/background1.png"), 0, 0);
|
||||
backgroundLayout->addWidget(createBackgroundCellWidget(tr("White Grid"),
|
||||
":/images/background2.png"), 0, 1);
|
||||
backgroundLayout->addWidget(createBackgroundCellWidget(tr("Gray Grid"),
|
||||
":/images/background3.png"), 1, 0);
|
||||
backgroundLayout->addWidget(createBackgroundCellWidget(tr("No Grid"),
|
||||
":/images/background4.png"), 1, 1);
|
||||
|
||||
backgroundLayout->setRowStretch(2, 10);
|
||||
backgroundLayout->setColumnStretch(2, 10);
|
||||
|
||||
QWidget *backgroundWidget = new QWidget;
|
||||
backgroundWidget->setLayout(backgroundLayout);
|
||||
|
||||
|
||||
//! [22]
|
||||
toolBox = new QToolBox;
|
||||
toolBox->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Ignored));
|
||||
toolBox->setMinimumWidth(itemWidget->sizeHint().width());
|
||||
toolBox->addItem(itemWidget, tr("Basic Flowchart Shapes"));
|
||||
toolBox->addItem(backgroundWidget, tr("Backgrounds"));
|
||||
}
|
||||
//! [22]
|
||||
|
||||
//! [23]
|
||||
void MainWindow::createActions()
|
||||
{
|
||||
toFrontAction = new QAction(QIcon(":/images/bringtofront.png"),
|
||||
tr("Bring to &Front"), this);
|
||||
toFrontAction->setShortcut(tr("Ctrl+F"));
|
||||
toFrontAction->setStatusTip(tr("Bring item to front"));
|
||||
connect(toFrontAction, &QAction::triggered, this, &MainWindow::bringToFront);
|
||||
//! [23]
|
||||
|
||||
sendBackAction = new QAction(QIcon(":/images/sendtoback.png"), tr("Send to &Back"), this);
|
||||
sendBackAction->setShortcut(tr("Ctrl+T"));
|
||||
sendBackAction->setStatusTip(tr("Send item to back"));
|
||||
connect(sendBackAction, &QAction::triggered, this, &MainWindow::sendToBack);
|
||||
|
||||
deleteAction = new QAction(QIcon(":/images/delete.png"), tr("&Delete"), this);
|
||||
deleteAction->setShortcut(tr("Delete"));
|
||||
deleteAction->setStatusTip(tr("Delete item from diagram"));
|
||||
connect(deleteAction, &QAction::triggered, this, &MainWindow::deleteItem);
|
||||
|
||||
exitAction = new QAction(tr("E&xit"), this);
|
||||
exitAction->setShortcuts(QKeySequence::Quit);
|
||||
exitAction->setStatusTip(tr("Quit Scenediagram example"));
|
||||
connect(exitAction, &QAction::triggered, this, &QWidget::close);
|
||||
|
||||
boldAction = new QAction(tr("Bold"), this);
|
||||
boldAction->setCheckable(true);
|
||||
QPixmap pixmap(":/images/bold.png");
|
||||
boldAction->setIcon(QIcon(pixmap));
|
||||
boldAction->setShortcut(tr("Ctrl+B"));
|
||||
connect(boldAction, &QAction::triggered, this, &MainWindow::handleFontChange);
|
||||
|
||||
italicAction = new QAction(QIcon(":/images/italic.png"), tr("Italic"), this);
|
||||
italicAction->setCheckable(true);
|
||||
italicAction->setShortcut(tr("Ctrl+I"));
|
||||
connect(italicAction, &QAction::triggered, this, &MainWindow::handleFontChange);
|
||||
|
||||
underlineAction = new QAction(QIcon(":/images/underline.png"), tr("Underline"), this);
|
||||
underlineAction->setCheckable(true);
|
||||
underlineAction->setShortcut(tr("Ctrl+U"));
|
||||
connect(underlineAction, &QAction::triggered, this, &MainWindow::handleFontChange);
|
||||
|
||||
aboutAction = new QAction(tr("A&bout"), this);
|
||||
aboutAction->setShortcut(tr("F1"));
|
||||
connect(aboutAction, &QAction::triggered, this, &MainWindow::about);
|
||||
}
|
||||
|
||||
//! [24]
|
||||
void MainWindow::createMenus()
|
||||
{
|
||||
fileMenu = menuBar()->addMenu(tr("&File"));
|
||||
fileMenu->addAction(exitAction);
|
||||
|
||||
itemMenu = menuBar()->addMenu(tr("&Item"));
|
||||
itemMenu->addAction(deleteAction);
|
||||
itemMenu->addSeparator();
|
||||
itemMenu->addAction(toFrontAction);
|
||||
itemMenu->addAction(sendBackAction);
|
||||
|
||||
aboutMenu = menuBar()->addMenu(tr("&Help"));
|
||||
aboutMenu->addAction(aboutAction);
|
||||
}
|
||||
//! [24]
|
||||
|
||||
//! [25]
|
||||
void MainWindow::createToolbars()
|
||||
{
|
||||
//! [25]
|
||||
editToolBar = addToolBar(tr("Edit"));
|
||||
editToolBar->addAction(deleteAction);
|
||||
editToolBar->addAction(toFrontAction);
|
||||
editToolBar->addAction(sendBackAction);
|
||||
|
||||
fontCombo = new QFontComboBox();
|
||||
connect(fontCombo, &QFontComboBox::currentFontChanged,
|
||||
this, &MainWindow::currentFontChanged);
|
||||
|
||||
fontSizeCombo = new QComboBox;
|
||||
fontSizeCombo->setEditable(true);
|
||||
for (int i = 8; i < 30; i = i + 2)
|
||||
fontSizeCombo->addItem(QString().setNum(i));
|
||||
QIntValidator *validator = new QIntValidator(2, 64, this);
|
||||
fontSizeCombo->setValidator(validator);
|
||||
connect(fontSizeCombo, &QComboBox::currentTextChanged,
|
||||
this, &MainWindow::fontSizeChanged);
|
||||
|
||||
fontColorToolButton = new QToolButton;
|
||||
fontColorToolButton->setPopupMode(QToolButton::MenuButtonPopup);
|
||||
fontColorToolButton->setMenu(createColorMenu(SLOT(textColorChanged()), Qt::black));
|
||||
textAction = fontColorToolButton->menu()->defaultAction();
|
||||
fontColorToolButton->setIcon(createColorToolButtonIcon(":/images/textpointer.png", Qt::black));
|
||||
fontColorToolButton->setAutoFillBackground(true);
|
||||
connect(fontColorToolButton, &QAbstractButton::clicked,
|
||||
this, &MainWindow::textButtonTriggered);
|
||||
|
||||
//! [26]
|
||||
fillColorToolButton = new QToolButton;
|
||||
fillColorToolButton->setPopupMode(QToolButton::MenuButtonPopup);
|
||||
fillColorToolButton->setMenu(createColorMenu(SLOT(itemColorChanged()), Qt::white));
|
||||
fillAction = fillColorToolButton->menu()->defaultAction();
|
||||
fillColorToolButton->setIcon(createColorToolButtonIcon(
|
||||
":/images/floodfill.png", Qt::white));
|
||||
connect(fillColorToolButton, &QAbstractButton::clicked,
|
||||
this, &MainWindow::fillButtonTriggered);
|
||||
//! [26]
|
||||
|
||||
lineColorToolButton = new QToolButton;
|
||||
lineColorToolButton->setPopupMode(QToolButton::MenuButtonPopup);
|
||||
lineColorToolButton->setMenu(createColorMenu(SLOT(lineColorChanged()), Qt::black));
|
||||
lineAction = lineColorToolButton->menu()->defaultAction();
|
||||
lineColorToolButton->setIcon(createColorToolButtonIcon(
|
||||
":/images/linecolor.png", Qt::black));
|
||||
connect(lineColorToolButton, &QAbstractButton::clicked,
|
||||
this, &MainWindow::lineButtonTriggered);
|
||||
|
||||
textToolBar = addToolBar(tr("Font"));
|
||||
textToolBar->addWidget(fontCombo);
|
||||
textToolBar->addWidget(fontSizeCombo);
|
||||
textToolBar->addAction(boldAction);
|
||||
textToolBar->addAction(italicAction);
|
||||
textToolBar->addAction(underlineAction);
|
||||
|
||||
colorToolBar = addToolBar(tr("Color"));
|
||||
colorToolBar->addWidget(fontColorToolButton);
|
||||
colorToolBar->addWidget(fillColorToolButton);
|
||||
colorToolBar->addWidget(lineColorToolButton);
|
||||
|
||||
QToolButton *pointerButton = new QToolButton;
|
||||
pointerButton->setCheckable(true);
|
||||
pointerButton->setChecked(true);
|
||||
pointerButton->setIcon(QIcon(":/images/pointer.png"));
|
||||
QToolButton *linePointerButton = new QToolButton;
|
||||
linePointerButton->setCheckable(true);
|
||||
linePointerButton->setIcon(QIcon(":/images/linepointer.png"));
|
||||
|
||||
pointerTypeGroup = new QButtonGroup(this);
|
||||
pointerTypeGroup->addButton(pointerButton, int(DiagramScene::MoveItem));
|
||||
pointerTypeGroup->addButton(linePointerButton, int(DiagramScene::InsertLine));
|
||||
connect(pointerTypeGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked),
|
||||
this, &MainWindow::pointerGroupClicked);
|
||||
|
||||
sceneScaleCombo = new QComboBox;
|
||||
QStringList scales;
|
||||
scales << tr("50%") << tr("75%") << tr("100%") << tr("125%") << tr("150%");
|
||||
sceneScaleCombo->addItems(scales);
|
||||
sceneScaleCombo->setCurrentIndex(2);
|
||||
connect(sceneScaleCombo, &QComboBox::currentTextChanged,
|
||||
this, &MainWindow::sceneScaleChanged);
|
||||
|
||||
pointerToolbar = addToolBar(tr("Pointer type"));
|
||||
pointerToolbar->addWidget(pointerButton);
|
||||
pointerToolbar->addWidget(linePointerButton);
|
||||
pointerToolbar->addWidget(sceneScaleCombo);
|
||||
//! [27]
|
||||
}
|
||||
//! [27]
|
||||
|
||||
//! [28]
|
||||
QWidget *MainWindow::createBackgroundCellWidget(const QString &text, const QString &image)
|
||||
{
|
||||
QToolButton *button = new QToolButton;
|
||||
button->setText(text);
|
||||
button->setIcon(QIcon(image));
|
||||
button->setIconSize(QSize(50, 50));
|
||||
button->setCheckable(true);
|
||||
backgroundButtonGroup->addButton(button);
|
||||
|
||||
QGridLayout *layout = new QGridLayout;
|
||||
layout->addWidget(button, 0, 0, Qt::AlignHCenter);
|
||||
layout->addWidget(new QLabel(text), 1, 0, Qt::AlignCenter);
|
||||
|
||||
QWidget *widget = new QWidget;
|
||||
widget->setLayout(layout);
|
||||
|
||||
return widget;
|
||||
}
|
||||
//! [28]
|
||||
|
||||
//! [29]
|
||||
QWidget *MainWindow::createCellWidget(const QString &text, DiagramItem::DiagramType type)
|
||||
{
|
||||
|
||||
DiagramItem item(type, itemMenu);
|
||||
QIcon icon(item.image());
|
||||
|
||||
QToolButton *button = new QToolButton;
|
||||
button->setIcon(icon);
|
||||
button->setIconSize(QSize(50, 50));
|
||||
button->setCheckable(true);
|
||||
buttonGroup->addButton(button, int(type));
|
||||
|
||||
QGridLayout *layout = new QGridLayout;
|
||||
layout->addWidget(button, 0, 0, Qt::AlignHCenter);
|
||||
layout->addWidget(new QLabel(text), 1, 0, Qt::AlignCenter);
|
||||
|
||||
QWidget *widget = new QWidget;
|
||||
widget->setLayout(layout);
|
||||
|
||||
return widget;
|
||||
}
|
||||
//! [29]
|
||||
|
||||
//! [30]
|
||||
QMenu *MainWindow::createColorMenu(const char *slot, QColor defaultColor)
|
||||
{
|
||||
QList<QColor> colors;
|
||||
colors << Qt::black << Qt::white << Qt::red << Qt::blue << Qt::yellow;
|
||||
QStringList names;
|
||||
names << tr("black") << tr("white") << tr("red") << tr("blue")
|
||||
<< tr("yellow");
|
||||
|
||||
QMenu *colorMenu = new QMenu(this);
|
||||
for (int i = 0; i < colors.count(); ++i) {
|
||||
QAction *action = new QAction(names.at(i), this);
|
||||
action->setData(colors.at(i));
|
||||
action->setIcon(createColorIcon(colors.at(i)));
|
||||
connect(action, SIGNAL(triggered()), this, slot);
|
||||
colorMenu->addAction(action);
|
||||
if (colors.at(i) == defaultColor)
|
||||
colorMenu->setDefaultAction(action);
|
||||
}
|
||||
return colorMenu;
|
||||
}
|
||||
//! [30]
|
||||
|
||||
//! [31]
|
||||
QIcon MainWindow::createColorToolButtonIcon(const QString &imageFile, QColor color)
|
||||
{
|
||||
QPixmap pixmap(50, 80);
|
||||
pixmap.fill(Qt::transparent);
|
||||
QPainter painter(&pixmap);
|
||||
QPixmap image(imageFile);
|
||||
// Draw icon centred horizontally on button.
|
||||
QRect target(4, 0, 42, 43);
|
||||
QRect source(0, 0, 42, 43);
|
||||
painter.fillRect(QRect(0, 60, 50, 80), color);
|
||||
painter.drawPixmap(target, image, source);
|
||||
|
||||
return QIcon(pixmap);
|
||||
}
|
||||
//! [31]
|
||||
|
||||
//! [32]
|
||||
QIcon MainWindow::createColorIcon(QColor color)
|
||||
{
|
||||
QPixmap pixmap(20, 20);
|
||||
QPainter painter(&pixmap);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.fillRect(QRect(0, 0, 20, 20), color);
|
||||
|
||||
return QIcon(pixmap);
|
||||
}
|
||||
//! [32]
|
113
examples/widgets/graphicsview/diagramscene/mainwindow.h
Normal file
@ -0,0 +1,113 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include "diagramitem.h"
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
class DiagramScene;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
class QToolBox;
|
||||
class QSpinBox;
|
||||
class QComboBox;
|
||||
class QFontComboBox;
|
||||
class QButtonGroup;
|
||||
class QLineEdit;
|
||||
class QGraphicsTextItem;
|
||||
class QFont;
|
||||
class QToolButton;
|
||||
class QAbstractButton;
|
||||
class QGraphicsView;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
//! [0]
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow();
|
||||
|
||||
private slots:
|
||||
void backgroundButtonGroupClicked(QAbstractButton *button);
|
||||
void buttonGroupClicked(QAbstractButton *button);
|
||||
void deleteItem();
|
||||
void pointerGroupClicked();
|
||||
void bringToFront();
|
||||
void sendToBack();
|
||||
void itemInserted(DiagramItem *item);
|
||||
void textInserted(QGraphicsTextItem *item);
|
||||
void currentFontChanged(const QFont &font);
|
||||
void fontSizeChanged(const QString &size);
|
||||
void sceneScaleChanged(const QString &scale);
|
||||
void textColorChanged();
|
||||
void itemColorChanged();
|
||||
void lineColorChanged();
|
||||
void textButtonTriggered();
|
||||
void fillButtonTriggered();
|
||||
void lineButtonTriggered();
|
||||
void handleFontChange();
|
||||
void itemSelected(QGraphicsItem *item);
|
||||
void about();
|
||||
|
||||
private:
|
||||
void createToolBox();
|
||||
void createActions();
|
||||
void createMenus();
|
||||
void createToolbars();
|
||||
QWidget *createBackgroundCellWidget(const QString &text,
|
||||
const QString &image);
|
||||
QWidget *createCellWidget(const QString &text,
|
||||
DiagramItem::DiagramType type);
|
||||
QMenu *createColorMenu(const char *slot, QColor defaultColor);
|
||||
QIcon createColorToolButtonIcon(const QString &image, QColor color);
|
||||
QIcon createColorIcon(QColor color);
|
||||
|
||||
DiagramScene *scene;
|
||||
QGraphicsView *view;
|
||||
|
||||
QAction *exitAction;
|
||||
QAction *addAction;
|
||||
QAction *deleteAction;
|
||||
|
||||
QAction *toFrontAction;
|
||||
QAction *sendBackAction;
|
||||
QAction *aboutAction;
|
||||
|
||||
QMenu *fileMenu;
|
||||
QMenu *itemMenu;
|
||||
QMenu *aboutMenu;
|
||||
|
||||
QToolBar *textToolBar;
|
||||
QToolBar *editToolBar;
|
||||
QToolBar *colorToolBar;
|
||||
QToolBar *pointerToolbar;
|
||||
|
||||
QComboBox *sceneScaleCombo;
|
||||
QComboBox *itemColorCombo;
|
||||
QComboBox *textColorCombo;
|
||||
QComboBox *fontSizeCombo;
|
||||
QFontComboBox *fontCombo;
|
||||
|
||||
QToolBox *toolBox;
|
||||
QButtonGroup *buttonGroup;
|
||||
QButtonGroup *pointerTypeGroup;
|
||||
QButtonGroup *backgroundButtonGroup;
|
||||
QToolButton *fontColorToolButton;
|
||||
QToolButton *fillColorToolButton;
|
||||
QToolButton *lineColorToolButton;
|
||||
QAction *boldAction;
|
||||
QAction *underlineAction;
|
||||
QAction *italicAction;
|
||||
QAction *textAction;
|
||||
QAction *fillAction;
|
||||
QAction *lineAction;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif // MAINWINDOW_H
|