From ebdd3f8ac8b6d27dad987e9598f507c54313ab19 Mon Sep 17 00:00:00 2001 From: luoliangyi <87842688@qq.com> Date: Mon, 14 Aug 2023 18:11:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=BE=E5=83=8F=E7=BC=96=E8=BE=91=E5=AF=B9?= =?UTF-8?q?=E8=AF=9D=E6=A1=86=E5=AE=9E=E7=8E=B0=E6=92=A4=E9=94=80=E3=80=81?= =?UTF-8?q?=E9=87=8D=E5=81=9A=E3=80=81=E6=B8=85=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/scanner2/dialog_imageeditor.cpp | 67 ++- app/scanner2/dialog_imageeditor.h | 9 + app/scanner2/dialog_imageeditor.ui | 739 ++++++++++++++++------------ app/scanner2/graphicsscene.cpp | 240 +++++++-- app/scanner2/graphicsscene.h | 19 +- 5 files changed, 692 insertions(+), 382 deletions(-) diff --git a/app/scanner2/dialog_imageeditor.cpp b/app/scanner2/dialog_imageeditor.cpp index 9fd8cfa1..0298e335 100644 --- a/app/scanner2/dialog_imageeditor.cpp +++ b/app/scanner2/dialog_imageeditor.cpp @@ -29,6 +29,11 @@ Dialog_ImageEditor::Dialog_ImageEditor(QWidget *parent) QColor backgroundColor = qRgb(240, 240, 240); ui->graphicsView->setBackgroundBrush(QBrush(backgroundColor)); + + connect(m_scene, SIGNAL(itemChanged()), this, SLOT(on_itemChanged())); + + ui->btn_undo->setEnabled(m_scene->isCanUndo()); + ui->btn_redo->setEnabled(m_scene->isCanRedo()); } Dialog_ImageEditor::~Dialog_ImageEditor() @@ -53,17 +58,23 @@ QImage Dialog_ImageEditor::exportImage() image.setDotsPerMeterX(m_dpi_x); image.setDotsPerMeterY(m_dpi_y); QPainter painter(&image); - m_scene->render(&painter); //¹Ø¼üº¯Êý + m_scene->render(&painter); //�ؼ����� return image; } +void Dialog_ImageEditor::on_itemChanged() +{ + ui->btn_undo->setEnabled(m_scene->isCanUndo()); + ui->btn_redo->setEnabled(m_scene->isCanRedo()); +} + void Dialog_ImageEditor::on_btn_rect_clicked(bool checked) { if (checked) { m_scene->setItemFlag(GraphicsScene::Rect); ui->btn_arrow->setChecked(false); - //ui->btn_rect->setChecked(false); + ui->btn_mask->setChecked(false); ui->btn_ellipse->setChecked(false); ui->btn_text->setChecked(false); ui->btn_line->setChecked(false); @@ -80,7 +91,7 @@ void Dialog_ImageEditor::on_btn_ellipse_clicked(bool checked) m_scene->setItemFlag(GraphicsScene::Ellipse); ui->btn_arrow->setChecked(false); ui->btn_rect->setChecked(false); - //ui->btn_ellipse->setChecked(false); + ui->btn_mask->setChecked(false); ui->btn_text->setChecked(false); ui->btn_line->setChecked(false); ui->btn_pen->setChecked(false); @@ -98,7 +109,7 @@ void Dialog_ImageEditor::on_btn_line_clicked(bool checked) ui->btn_rect->setChecked(false); ui->btn_ellipse->setChecked(false); ui->btn_text->setChecked(false); - //ui->btn_line->setChecked(false); + ui->btn_mask->setChecked(false); ui->btn_pen->setChecked(false); } else @@ -113,7 +124,7 @@ void Dialog_ImageEditor::on_btn_text_clicked(bool checked) ui->btn_arrow->setChecked(false); ui->btn_rect->setChecked(false); ui->btn_ellipse->setChecked(false); - //ui->btn_text->setChecked(false); + ui->btn_mask->setChecked(false); ui->btn_line->setChecked(false); ui->btn_pen->setChecked(false); } @@ -126,7 +137,7 @@ void Dialog_ImageEditor::on_btn_arrow_clicked(bool checked) if (checked) { m_scene->setItemFlag(GraphicsScene::Arrow); - //ui->btn_arrow->setChecked(false); + ui->btn_mask->setChecked(false); ui->btn_rect->setChecked(false); ui->btn_ellipse->setChecked(false); ui->btn_text->setChecked(false); @@ -147,7 +158,7 @@ void Dialog_ImageEditor::on_btn_pen_clicked(bool checked) ui->btn_ellipse->setChecked(false); ui->btn_text->setChecked(false); ui->btn_line->setChecked(false); - //ui->btn_pen->setChecked(false); + ui->btn_mask->setChecked(false); } else m_scene->setItemFlag(GraphicsScene::None); @@ -155,8 +166,9 @@ void Dialog_ImageEditor::on_btn_pen_clicked(bool checked) void Dialog_ImageEditor::on_btn_color_clicked() { - QColorDialog dlg; - if (!dlg.exec()) return; + QColorDialog dlg(this); + if (!dlg.exec()) + return; ui->btn_color->setStyleSheet(QString("QPushButton{background-color:%1;border:1px solid %2}").arg(dlg.selectedColor().name()).arg(dlg.selectedColor().name())); m_scene->setColor(dlg.selectedColor()); @@ -174,7 +186,10 @@ void Dialog_ImageEditor::on_comboBox_textSize_currentIndexChanged(int index) void Dialog_ImageEditor::on_btn_undo_clicked() { - m_scene->unDo(); + m_scene->undo(); + + ui->btn_undo->setEnabled(m_scene->isCanUndo()); + ui->btn_redo->setEnabled(m_scene->isCanRedo()); } void Dialog_ImageEditor::on_btn_ok_clicked() @@ -256,3 +271,35 @@ void Dialog_ImageEditor::resizeEvent(QResizeEvent* event) QDialog::resizeEvent(event); } + +void Dialog_ImageEditor::on_btn_redo_clicked() +{ + m_scene->redo(); + + ui->btn_undo->setEnabled(m_scene->isCanUndo()); + ui->btn_redo->setEnabled(m_scene->isCanRedo()); +} + +void Dialog_ImageEditor::on_btn_clear_clicked() +{ + m_scene->clear(); + + ui->btn_undo->setEnabled(m_scene->isCanUndo()); + ui->btn_redo->setEnabled(m_scene->isCanRedo()); +} + +void Dialog_ImageEditor::on_btn_mask_clicked(bool checked) +{ + if (checked) + { + m_scene->setItemFlag(GraphicsScene::Mask); + ui->btn_arrow->setChecked(false); + ui->btn_rect->setChecked(false); + ui->btn_ellipse->setChecked(false); + ui->btn_text->setChecked(false); + ui->btn_line->setChecked(false); + ui->btn_pen->setChecked(false); + } + else + m_scene->setItemFlag(GraphicsScene::None); +} diff --git a/app/scanner2/dialog_imageeditor.h b/app/scanner2/dialog_imageeditor.h index 15bdb708..408a8f55 100644 --- a/app/scanner2/dialog_imageeditor.h +++ b/app/scanner2/dialog_imageeditor.h @@ -22,6 +22,9 @@ public: QImage exportImage(); +private slots: + void on_itemChanged(); + private slots: void on_btn_rect_clicked(bool checked); @@ -55,6 +58,12 @@ private slots: void on_btn_fit_clicked(); + void on_btn_redo_clicked(); + + void on_btn_clear_clicked(); + + void on_btn_mask_clicked(bool checked); + protected: void resizeEvent(QResizeEvent* event); diff --git a/app/scanner2/dialog_imageeditor.ui b/app/scanner2/dialog_imageeditor.ui index d3fc3dfe..6646b219 100644 --- a/app/scanner2/dialog_imageeditor.ui +++ b/app/scanner2/dialog_imageeditor.ui @@ -6,366 +6,451 @@ 0 0 - 1383 - 378 + 1093 + 607 Dialog_ImageEditor - - - 0 - + - - - - + - - - Qt::NoFocus - - - rect - - - Rect - - - true - - - - - - - Qt::NoFocus - - - ellipse - - - Ellipse - - - true - - - - - - - Qt::NoFocus - - - line - - - Line - - - true - - - - - - - Qt::NoFocus - - - Pen - - - true - - - - - - - Qt::NoFocus - - - arrow - - - Arrow - - - true - - - - - - - Qt::NoFocus - - - text - - - Text - - - true - - - - - - - Color - - - - - - - - 30 - 30 - - - - Qt::NoFocus - - - color - - - - - - - - - - LineWidth - - - - - - - - 80 - 0 - - + - - 1 pix - + + + Qt::NoFocus + + + rect + + + Rect + + + true + + - - 3 pix - + + + Qt::NoFocus + + + ellipse + + + Ellipse + + + true + + - - 5 pix - + + + Qt::NoFocus + + + line + + + Line + + + true + + - - 8 pix - - - - - - - - TextSize - - - - - - - - 70 - 0 - - - - 0 - - - - 20 - + + + Qt::NoFocus + + + arrow + + + Arrow + + + true + + - - 26 - + + + Qt::NoFocus + + + Pen + + + true + + - - 36 - + + + Qt::NoFocus + + + text + + + Text + + + true + + - - 48 - + + + Qt::NoFocus + + + mask + + + Mask + + + true + + - - 72 - + + + Qt::Vertical + + + + 20 + 40 + + + - - 96 - + + + + + Color + + + + + + + + 30 + 30 + + + + Qt::NoFocus + + + color + + + + + + + - - 128 - + + + + + LineWidth + + + + + + + + 80 + 0 + + + + + 1 pix + + + + + 3 pix + + + + + 5 pix + + + + + 8 pix + + + + + - - 160 - + + + + + TextSize + + + + + + + + 70 + 0 + + + + 0 + + + + 20 + + + + + 26 + + + + + 36 + + + + + 48 + + + + + 72 + + + + + 96 + + + + + 128 + + + + + 160 + + + + + 200 + + + + + - - 200 - + + + Qt::Vertical + + + QSizePolicy::Maximum + + + + 20 + 30 + + + - + - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::NoFocus - - - zoomin - - - Zoomin - - - - - - - fit - - - Fit - - - - - - - Qt::NoFocus - - - 100% - - - 1:1 - - - - - - - Qt::NoFocus - - - zoomout - - - Zoomout - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::NoFocus - - - undo - - - Undo - - - Ctrl+Z - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - ok - - - Ok - - - - - - - cancel - - - Cancel - - + + + + + + + + + + Qt::NoFocus + + + undo + + + Undo + + + Ctrl+Z + + + + + + + Qt::NoFocus + + + redo + + + Redo + + + Ctrl+Z + + + + + + + Qt::NoFocus + + + clear + + + Clear + + + Ctrl+Z + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::NoFocus + + + zoomin + + + Zoomin + + + + + + + fit + + + Fit + + + + + + + Qt::NoFocus + + + 100% + + + 1:1 + + + + + + + Qt::NoFocus + + + zoomout + + + Zoomout + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + ok + + + Ok + + + + + + + cancel + + + Cancel + + + + + + diff --git a/app/scanner2/graphicsscene.cpp b/app/scanner2/graphicsscene.cpp index b38d8939..7ddaf43a 100644 --- a/app/scanner2/graphicsscene.cpp +++ b/app/scanner2/graphicsscene.cpp @@ -69,16 +69,24 @@ GraphicsScene::GraphicsScene(QObject* parent) : QGraphicsScene(parent) , m_status(Normal) , m_activeItem(nullptr) - , m_btn_pressed(0) , m_pen(QColor(255, 0, 0, 255)) , m_brush(QColor(255, 255, 255, 255)) , m_font(tr("SongTi")) , m_edit(nullptr) { + m_ItemList.clear(); + m_curItemIndex = -1; } GraphicsScene::~GraphicsScene() { + for (int i = 0; i < (int)m_ItemList.size(); ++i) + { + delete m_ItemList[i]; + m_ItemList[i] = nullptr; + } + m_ItemList.clear(); + m_curItemIndex = -1; } void GraphicsScene::setColor(const QColor& color) @@ -101,33 +109,13 @@ void GraphicsScene::setLineWidth(int width) void GraphicsScene::setItemFlag(int flag) { - if (m_status == CreateText) - { - if (m_activeItem != nullptr) - { - QString text = m_edit->document()->toPlainText(); - QFont font = m_edit->font(); - removeItem(m_activeItem); - QGraphicsTextItem* item = addText(text, font); - item->setPos(m_edit->mapToParent(QPoint())); - item->setDefaultTextColor(m_pen.color()); - delete m_edit; - m_edit = nullptr; - m_activeItem = nullptr; - } - } - - if (m_activeItem != nullptr) - { - if (typeid(*m_activeItem) == typeid(QGraphicsProxyWidget)) - removeItem(m_activeItem); - - m_activeItem = nullptr; - m_status = Normal; - } + flush(); switch (flag) { + case Mask: + m_status = CreateMask; + break; case Rect: m_status = CreateRect; break; @@ -152,15 +140,62 @@ void GraphicsScene::setItemFlag(int flag) } } -void GraphicsScene::unDo() +bool GraphicsScene::isCanUndo() { - m_activeItem = nullptr; + if (m_ItemList.empty() || -1 == m_curItemIndex) + return false; + return true; +} - QList items = this->items(); - if (items.count() < 2) +void GraphicsScene::undo() +{ + flush(); + + if (!isCanUndo()) return; - removeItem(items.first()); + --m_curItemIndex; + updateShow(); +} + +bool GraphicsScene::isCanRedo() +{ + if (m_ItemList.empty() || (int)m_ItemList.size() - 1 == m_curItemIndex) + return false; + return true; +} + +void GraphicsScene::redo() +{ + flush(); + + if (!isCanRedo()) + return; + + ++m_curItemIndex; + updateShow(); +} + +void GraphicsScene::clear() +{ + flush(); + + if (m_ItemList.empty()) + return; + if (-1 == m_curItemIndex) + return; + if (NULL == m_ItemList[m_curItemIndex]) + return; + + for (int i = (int)m_ItemList.size() - 1; i > m_curItemIndex; --i) + { + delete m_ItemList[i]; + m_ItemList[i] = nullptr; + m_ItemList.erase(m_ItemList.begin() + i); + } + m_ItemList.push_back(NULL); + ++m_curItemIndex; + updateShow(); } #define PI acos(-1) @@ -179,6 +214,92 @@ float lineLength(const QPointF& p1, const QPointF& p2) return sqrt(pow(p1.x() - p2.x(), 2) + pow(p1.y() - p2.y(), 2)); } +void GraphicsScene::flush() +{ + if (nullptr == m_activeItem) + { + return; + } + + if (m_status == CreateText) + { + assert(typeid(*m_activeItem) == typeid(QGraphicsProxyWidget)); + + QString text = m_edit->document()->toPlainText(); + QFont font = m_edit->font(); + removeItem(m_activeItem); + m_activeItem = nullptr; + QGraphicsTextItem* item = addText(text, font); + item->setPos(m_edit->mapToParent(QPoint())); + item->setDefaultTextColor(m_pen.color()); + for (int i = (int)m_ItemList.size() - 1; i > m_curItemIndex; --i) + { + delete m_ItemList[i]; + m_ItemList[i] = nullptr; + m_ItemList.erase(m_ItemList.begin() + i); + } + m_ItemList.push_back(item); + ++m_curItemIndex; + + delete m_edit; + m_edit = nullptr; + } + else + { + assert(typeid(*m_activeItem) != typeid(QGraphicsProxyWidget)); + + for (int i = (int)m_ItemList.size() - 1; i > m_curItemIndex; --i) + { + delete m_ItemList[i]; + m_ItemList[i] = nullptr; + m_ItemList.erase(m_ItemList.begin() + i); + } + m_ItemList.push_back(m_activeItem); + ++m_curItemIndex; + m_activeItem = nullptr; + } +} + +void GraphicsScene::updateShow() +{ + if (m_ItemList.empty() || -1 == m_curItemIndex || NULL == m_ItemList[m_curItemIndex]) + { + while (1) + { + QList items = this->items(); + if (items.count() < 2) + break; + removeItem(items.first()); + } + + return; + } + + int startIndex = m_curItemIndex; + for (int i = m_curItemIndex; i >= 0; --i) + { + if (m_ItemList[i] == NULL) + { + break; + } + + startIndex = i; + } + + while (1) + { + QList items = this->items(); + if (items.count() < 2) + break; + removeItem(items.first()); + } + + for (int i = startIndex; i <= m_curItemIndex; ++i) + { + this->addItem(m_ItemList[i]); + } +} + QPainterPath GraphicsScene::createArrowPath(const QPointF& p1, const QPointF& p2) { float angle; @@ -225,7 +346,17 @@ void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) if (!sceneRect().contains(mouseEvent->scenePos())) return; - if (m_status == CreateRect) + if (m_status == CreateMask) + { + QGraphicsRectItem* item = reinterpret_cast(m_activeItem); + QPointF pos = mouseEvent->scenePos(); + float left = qMin(pos.x(), m_startPoint.x()); + float top = qMin(pos.y(), m_startPoint.y()); + float right = qMax(pos.x(), m_startPoint.x()); + float bottom = qMax(pos.y(), m_startPoint.y()); + item->setRect(QRectF(QPointF(left, top), QPointF(right, bottom))); + } + else if (m_status == CreateRect) { QGraphicsRectItem* item = reinterpret_cast(m_activeItem); QPointF pos = mouseEvent->scenePos(); @@ -266,16 +397,16 @@ void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { - if (mouseEvent->button() == Qt::MouseButton::LeftButton) - m_btn_pressed = 1; - else if (mouseEvent->button() == Qt::MouseButton::RightButton) - m_btn_pressed = 2; - - if (m_status == CreateRect) + if (m_status == CreateMask) { m_activeItem = addRect(QRectF(mouseEvent->scenePos(), QSize(1, 1)), QPen(m_brush.color()), m_brush); m_startPoint = mouseEvent->scenePos(); } + else if (m_status == CreateRect) + { + m_activeItem = addRect(QRectF(mouseEvent->scenePos(), QSize(1, 1)), m_pen, QBrush()); + m_startPoint = mouseEvent->scenePos(); + } else if (m_status == CreateEllipse) { m_activeItem = addEllipse(QRectF(mouseEvent->scenePos(), QSize(1, 1)), m_pen, QBrush()); @@ -308,30 +439,38 @@ void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) return; } - m_btn_pressed = 0; - if (m_activeItem != nullptr) - if (typeid(*m_activeItem) != typeid(QGraphicsProxyWidget)) - m_activeItem = nullptr; if (m_status == CreateText) { if (m_activeItem != nullptr) { + assert(typeid(*m_activeItem) == typeid(QGraphicsProxyWidget)); QRectF r(m_edit->mapToParent(QPoint()), m_edit->size()); if (r.contains(mouseEvent->scenePos())) { QGraphicsScene::mouseReleaseEvent(mouseEvent); return; } + QString text = m_edit->document()->toPlainText(); QFont font = m_edit->font(); removeItem(m_activeItem); + m_activeItem = nullptr; QGraphicsTextItem* item = addText(text, font); item->setPos(m_edit->mapToParent(QPoint())); item->setDefaultTextColor(m_pen.color()); + for (int i = (int)m_ItemList.size() - 1; i > m_curItemIndex; --i) + { + delete m_ItemList[i]; + m_ItemList[i] = nullptr; + m_ItemList.erase(m_ItemList.begin() + i); + } + m_ItemList.push_back(item); + ++m_curItemIndex; + delete m_edit; m_edit = nullptr; - m_activeItem = nullptr; + emit itemChanged(); } else { @@ -343,6 +482,23 @@ void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) m_activeItem = widget; m_edit->setFocus(); } + } + else + { + if (m_activeItem != nullptr) + { + assert(typeid(*m_activeItem) != typeid(QGraphicsProxyWidget)); + for (int i = (int)m_ItemList.size() - 1; i > m_curItemIndex; --i) + { + delete m_ItemList[i]; + m_ItemList[i] = nullptr; + m_ItemList.erase(m_ItemList.begin() + i); + } + m_ItemList.push_back(m_activeItem); + ++m_curItemIndex; + m_activeItem = nullptr; + emit itemChanged(); + } } } diff --git a/app/scanner2/graphicsscene.h b/app/scanner2/graphicsscene.h index af501275..cbd173e7 100644 --- a/app/scanner2/graphicsscene.h +++ b/app/scanner2/graphicsscene.h @@ -3,8 +3,8 @@ #include #include - #include +#include class GraphicsTextEdit : public QTextEdit { @@ -29,6 +29,7 @@ public: enum STATUS { Normal = 0, + CreateMask, CreateRect, CreateEllipse, CreateLine, @@ -41,6 +42,7 @@ public: enum { None, + Mask, Rect, Ellipse, Line, @@ -61,8 +63,18 @@ public: void setItemFlag(int flag); - void unDo(); + bool isCanUndo(); + void undo(); + bool isCanRedo(); + void redo(); + void clear(); + +signals: + void itemChanged(); + private: + void flush(); + void updateShow(); QPainterPath createArrowPath(const QPointF& p1, const QPointF& p2); protected: @@ -72,12 +84,13 @@ protected: private: STATUS m_status; QGraphicsItem* m_activeItem; - int m_btn_pressed; QPointF m_startPoint; QPen m_pen; QBrush m_brush; QFont m_font; GraphicsTextEdit* m_edit; + std::vector m_ItemList; + int m_curItemIndex; }; #endif // GRAPHICSSCENE_H