图像编辑对话框实现撤销、重做、清理功能

This commit is contained in:
luoliangyi 2023-08-14 18:11:27 +08:00
parent 3d8b7b4218
commit ebdd3f8ac8
5 changed files with 692 additions and 382 deletions

View File

@ -29,6 +29,11 @@ Dialog_ImageEditor::Dialog_ImageEditor(QWidget *parent)
QColor backgroundColor = qRgb(240, 240, 240); QColor backgroundColor = qRgb(240, 240, 240);
ui->graphicsView->setBackgroundBrush(QBrush(backgroundColor)); 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() Dialog_ImageEditor::~Dialog_ImageEditor()
@ -53,17 +58,23 @@ QImage Dialog_ImageEditor::exportImage()
image.setDotsPerMeterX(m_dpi_x); image.setDotsPerMeterX(m_dpi_x);
image.setDotsPerMeterY(m_dpi_y); image.setDotsPerMeterY(m_dpi_y);
QPainter painter(&image); QPainter painter(&image);
m_scene->render(&painter); //¹Ø¼üº¯Êý m_scene->render(&painter); //<EFBFBD>ؼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return image; 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) void Dialog_ImageEditor::on_btn_rect_clicked(bool checked)
{ {
if (checked) if (checked)
{ {
m_scene->setItemFlag(GraphicsScene::Rect); m_scene->setItemFlag(GraphicsScene::Rect);
ui->btn_arrow->setChecked(false); ui->btn_arrow->setChecked(false);
//ui->btn_rect->setChecked(false); ui->btn_mask->setChecked(false);
ui->btn_ellipse->setChecked(false); ui->btn_ellipse->setChecked(false);
ui->btn_text->setChecked(false); ui->btn_text->setChecked(false);
ui->btn_line->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); m_scene->setItemFlag(GraphicsScene::Ellipse);
ui->btn_arrow->setChecked(false); ui->btn_arrow->setChecked(false);
ui->btn_rect->setChecked(false); ui->btn_rect->setChecked(false);
//ui->btn_ellipse->setChecked(false); ui->btn_mask->setChecked(false);
ui->btn_text->setChecked(false); ui->btn_text->setChecked(false);
ui->btn_line->setChecked(false); ui->btn_line->setChecked(false);
ui->btn_pen->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_rect->setChecked(false);
ui->btn_ellipse->setChecked(false); ui->btn_ellipse->setChecked(false);
ui->btn_text->setChecked(false); ui->btn_text->setChecked(false);
//ui->btn_line->setChecked(false); ui->btn_mask->setChecked(false);
ui->btn_pen->setChecked(false); ui->btn_pen->setChecked(false);
} }
else else
@ -113,7 +124,7 @@ void Dialog_ImageEditor::on_btn_text_clicked(bool checked)
ui->btn_arrow->setChecked(false); ui->btn_arrow->setChecked(false);
ui->btn_rect->setChecked(false); ui->btn_rect->setChecked(false);
ui->btn_ellipse->setChecked(false); ui->btn_ellipse->setChecked(false);
//ui->btn_text->setChecked(false); ui->btn_mask->setChecked(false);
ui->btn_line->setChecked(false); ui->btn_line->setChecked(false);
ui->btn_pen->setChecked(false); ui->btn_pen->setChecked(false);
} }
@ -126,7 +137,7 @@ void Dialog_ImageEditor::on_btn_arrow_clicked(bool checked)
if (checked) if (checked)
{ {
m_scene->setItemFlag(GraphicsScene::Arrow); m_scene->setItemFlag(GraphicsScene::Arrow);
//ui->btn_arrow->setChecked(false); ui->btn_mask->setChecked(false);
ui->btn_rect->setChecked(false); ui->btn_rect->setChecked(false);
ui->btn_ellipse->setChecked(false); ui->btn_ellipse->setChecked(false);
ui->btn_text->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_ellipse->setChecked(false);
ui->btn_text->setChecked(false); ui->btn_text->setChecked(false);
ui->btn_line->setChecked(false); ui->btn_line->setChecked(false);
//ui->btn_pen->setChecked(false); ui->btn_mask->setChecked(false);
} }
else else
m_scene->setItemFlag(GraphicsScene::None); 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() void Dialog_ImageEditor::on_btn_color_clicked()
{ {
QColorDialog dlg; QColorDialog dlg(this);
if (!dlg.exec()) return; 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())); 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()); 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() 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() void Dialog_ImageEditor::on_btn_ok_clicked()
@ -256,3 +271,35 @@ void Dialog_ImageEditor::resizeEvent(QResizeEvent* event)
QDialog::resizeEvent(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);
}

View File

@ -22,6 +22,9 @@ public:
QImage exportImage(); QImage exportImage();
private slots:
void on_itemChanged();
private slots: private slots:
void on_btn_rect_clicked(bool checked); void on_btn_rect_clicked(bool checked);
@ -55,6 +58,12 @@ private slots:
void on_btn_fit_clicked(); void on_btn_fit_clicked();
void on_btn_redo_clicked();
void on_btn_clear_clicked();
void on_btn_mask_clicked(bool checked);
protected: protected:
void resizeEvent(QResizeEvent* event); void resizeEvent(QResizeEvent* event);

View File

@ -6,366 +6,451 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1383</width> <width>1093</width>
<height>378</height> <height>607</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Dialog_ImageEditor</string> <string>Dialog_ImageEditor</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout_3">
<property name="topMargin">
<number>0</number>
</property>
<item> <item>
<widget class="QGraphicsView" name="graphicsView"/> <layout class="QHBoxLayout" name="horizontalLayout_5">
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QPushButton" name="btn_rect"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>rect</string>
</property>
<property name="text">
<string>Rect</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_ellipse">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>ellipse</string>
</property>
<property name="text">
<string>Ellipse</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_line">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>line</string>
</property>
<property name="text">
<string>Line</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_pen">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Pen</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_arrow">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>arrow</string>
</property>
<property name="text">
<string>Arrow</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_text">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>text</string>
</property>
<property name="text">
<string>Text</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Color</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_color">
<property name="minimumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>color</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>LineWidth</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_lineWidth">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<item> <item>
<property name="text"> <widget class="QPushButton" name="btn_rect">
<string>1 pix</string> <property name="focusPolicy">
</property> <enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>rect</string>
</property>
<property name="text">
<string>Rect</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item> </item>
<item> <item>
<property name="text"> <widget class="QPushButton" name="btn_ellipse">
<string>3 pix</string> <property name="focusPolicy">
</property> <enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>ellipse</string>
</property>
<property name="text">
<string>Ellipse</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item> </item>
<item> <item>
<property name="text"> <widget class="QPushButton" name="btn_line">
<string>5 pix</string> <property name="focusPolicy">
</property> <enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>line</string>
</property>
<property name="text">
<string>Line</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item> </item>
<item> <item>
<property name="text"> <widget class="QPushButton" name="btn_arrow">
<string>8 pix</string> <property name="focusPolicy">
</property> <enum>Qt::NoFocus</enum>
</item> </property>
</widget> <property name="toolTip">
</item> <string>arrow</string>
<item> </property>
<widget class="QLabel" name="label_2"> <property name="text">
<property name="text"> <string>Arrow</string>
<string>TextSize</string> </property>
</property> <property name="checkable">
</widget> <bool>true</bool>
</item> </property>
<item> </widget>
<widget class="QComboBox" name="comboBox_textSize">
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>20</string>
</property>
</item> </item>
<item> <item>
<property name="text"> <widget class="QPushButton" name="btn_pen">
<string>26</string> <property name="focusPolicy">
</property> <enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Pen</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item> </item>
<item> <item>
<property name="text"> <widget class="QPushButton" name="btn_text">
<string>36</string> <property name="focusPolicy">
</property> <enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>text</string>
</property>
<property name="text">
<string>Text</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item> </item>
<item> <item>
<property name="text"> <widget class="QPushButton" name="btn_mask">
<string>48</string> <property name="focusPolicy">
</property> <enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>mask</string>
</property>
<property name="text">
<string>Mask</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item> </item>
<item> <item>
<property name="text"> <spacer name="verticalSpacer_2">
<string>72</string> <property name="orientation">
</property> <enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item> </item>
<item> <item>
<property name="text"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<string>96</string> <item>
</property> <widget class="QLabel" name="label_3">
<property name="text">
<string>Color</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_color">
<property name="minimumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>color</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<property name="text"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<string>128</string> <item>
</property> <widget class="QLabel" name="label">
<property name="text">
<string>LineWidth</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_lineWidth">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<item>
<property name="text">
<string>1 pix</string>
</property>
</item>
<item>
<property name="text">
<string>3 pix</string>
</property>
</item>
<item>
<property name="text">
<string>5 pix</string>
</property>
</item>
<item>
<property name="text">
<string>8 pix</string>
</property>
</item>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<property name="text"> <layout class="QHBoxLayout" name="horizontalLayout_4">
<string>160</string> <item>
</property> <widget class="QLabel" name="label_2">
<property name="text">
<string>TextSize</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_textSize">
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>20</string>
</property>
</item>
<item>
<property name="text">
<string>26</string>
</property>
</item>
<item>
<property name="text">
<string>36</string>
</property>
</item>
<item>
<property name="text">
<string>48</string>
</property>
</item>
<item>
<property name="text">
<string>72</string>
</property>
</item>
<item>
<property name="text">
<string>96</string>
</property>
</item>
<item>
<property name="text">
<string>128</string>
</property>
</item>
<item>
<property name="text">
<string>160</string>
</property>
</item>
<item>
<property name="text">
<string>200</string>
</property>
</item>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<property name="text"> <spacer name="verticalSpacer">
<string>200</string> <property name="orientation">
</property> <enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>30</height>
</size>
</property>
</spacer>
</item> </item>
</widget> </layout>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<property name="orientation"> <item>
<enum>Qt::Horizontal</enum> <widget class="QGraphicsView" name="graphicsView"/>
</property> </item>
<property name="sizeHint" stdset="0"> <item>
<size> <layout class="QHBoxLayout" name="horizontalLayout">
<width>40</width> <item>
<height>20</height> <widget class="QPushButton" name="btn_undo">
</size> <property name="focusPolicy">
</property> <enum>Qt::NoFocus</enum>
</spacer> </property>
</item> <property name="toolTip">
<item> <string>undo</string>
<widget class="QPushButton" name="btn_zoomIn"> </property>
<property name="focusPolicy"> <property name="text">
<enum>Qt::NoFocus</enum> <string>Undo</string>
</property> </property>
<property name="toolTip"> <property name="shortcut">
<string>zoomin</string> <string>Ctrl+Z</string>
</property> </property>
<property name="text"> </widget>
<string>Zoomin</string> </item>
</property> <item>
</widget> <widget class="QPushButton" name="btn_redo">
</item> <property name="focusPolicy">
<item> <enum>Qt::NoFocus</enum>
<widget class="QPushButton" name="btn_fit"> </property>
<property name="toolTip"> <property name="toolTip">
<string>fit</string> <string>redo</string>
</property> </property>
<property name="text"> <property name="text">
<string>Fit</string> <string>Redo</string>
</property> </property>
</widget> <property name="shortcut">
</item> <string>Ctrl+Z</string>
<item> </property>
<widget class="QPushButton" name="btn_zoom"> </widget>
<property name="focusPolicy"> </item>
<enum>Qt::NoFocus</enum> <item>
</property> <widget class="QPushButton" name="btn_clear">
<property name="toolTip"> <property name="focusPolicy">
<string>100%</string> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="text"> <property name="toolTip">
<string>1:1</string> <string>clear</string>
</property> </property>
</widget> <property name="text">
</item> <string>Clear</string>
<item> </property>
<widget class="QPushButton" name="btn_zoomOut"> <property name="shortcut">
<property name="focusPolicy"> <string>Ctrl+Z</string>
<enum>Qt::NoFocus</enum> </property>
</property> </widget>
<property name="toolTip"> </item>
<string>zoomout</string> <item>
</property> <spacer name="horizontalSpacer_4">
<property name="text"> <property name="orientation">
<string>Zoomout</string> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> <property name="sizeHint" stdset="0">
</item> <size>
<item> <width>40</width>
<spacer name="horizontalSpacer_4"> <height>20</height>
<property name="orientation"> </size>
<enum>Qt::Horizontal</enum> </property>
</property> </spacer>
<property name="sizeHint" stdset="0"> </item>
<size> <item>
<width>40</width> <widget class="QPushButton" name="btn_zoomIn">
<height>20</height> <property name="focusPolicy">
</size> <enum>Qt::NoFocus</enum>
</property> </property>
</spacer> <property name="toolTip">
</item> <string>zoomin</string>
<item> </property>
<widget class="QPushButton" name="btn_undo"> <property name="text">
<property name="focusPolicy"> <string>Zoomin</string>
<enum>Qt::NoFocus</enum> </property>
</property> </widget>
<property name="toolTip"> </item>
<string>undo</string> <item>
</property> <widget class="QPushButton" name="btn_fit">
<property name="text"> <property name="toolTip">
<string>Undo</string> <string>fit</string>
</property> </property>
<property name="shortcut"> <property name="text">
<string>Ctrl+Z</string> <string>Fit</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer_3"> <widget class="QPushButton" name="btn_zoom">
<property name="orientation"> <property name="focusPolicy">
<enum>Qt::Horizontal</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="toolTip">
<size> <string>100%</string>
<width>40</width> </property>
<height>20</height> <property name="text">
</size> <string>1:1</string>
</property> </property>
</spacer> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="btn_ok"> <widget class="QPushButton" name="btn_zoomOut">
<property name="toolTip"> <property name="focusPolicy">
<string>ok</string> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="text"> <property name="toolTip">
<string>Ok</string> <string>zoomout</string>
</property> </property>
</widget> <property name="text">
</item> <string>Zoomout</string>
<item> </property>
<widget class="QPushButton" name="btn_cancel"> </widget>
<property name="toolTip"> </item>
<string>cancel</string> <item>
</property> <spacer name="horizontalSpacer_3">
<property name="text"> <property name="orientation">
<string>Cancel</string> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> <property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btn_ok">
<property name="toolTip">
<string>ok</string>
</property>
<property name="text">
<string>Ok</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_cancel">
<property name="toolTip">
<string>cancel</string>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item> </item>
</layout> </layout>
</item> </item>

View File

@ -69,16 +69,24 @@ GraphicsScene::GraphicsScene(QObject* parent)
: QGraphicsScene(parent) : QGraphicsScene(parent)
, m_status(Normal) , m_status(Normal)
, m_activeItem(nullptr) , m_activeItem(nullptr)
, m_btn_pressed(0)
, m_pen(QColor(255, 0, 0, 255)) , m_pen(QColor(255, 0, 0, 255))
, m_brush(QColor(255, 255, 255, 255)) , m_brush(QColor(255, 255, 255, 255))
, m_font(tr("SongTi")) , m_font(tr("SongTi"))
, m_edit(nullptr) , m_edit(nullptr)
{ {
m_ItemList.clear();
m_curItemIndex = -1;
} }
GraphicsScene::~GraphicsScene() 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) void GraphicsScene::setColor(const QColor& color)
@ -101,33 +109,13 @@ void GraphicsScene::setLineWidth(int width)
void GraphicsScene::setItemFlag(int flag) void GraphicsScene::setItemFlag(int flag)
{ {
if (m_status == CreateText) flush();
{
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;
}
switch (flag) switch (flag)
{ {
case Mask:
m_status = CreateMask;
break;
case Rect: case Rect:
m_status = CreateRect; m_status = CreateRect;
break; 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<QGraphicsItem*> items = this->items(); void GraphicsScene::undo()
if (items.count() < 2) {
flush();
if (!isCanUndo())
return; 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) #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)); 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<QGraphicsItem*> 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<QGraphicsItem*> 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) QPainterPath GraphicsScene::createArrowPath(const QPointF& p1, const QPointF& p2)
{ {
float angle; float angle;
@ -225,7 +346,17 @@ void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
if (!sceneRect().contains(mouseEvent->scenePos())) if (!sceneRect().contains(mouseEvent->scenePos()))
return; return;
if (m_status == CreateRect) if (m_status == CreateMask)
{
QGraphicsRectItem* item = reinterpret_cast<QGraphicsRectItem*>(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<QGraphicsRectItem*>(m_activeItem); QGraphicsRectItem* item = reinterpret_cast<QGraphicsRectItem*>(m_activeItem);
QPointF pos = mouseEvent->scenePos(); QPointF pos = mouseEvent->scenePos();
@ -266,16 +397,16 @@ void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{ {
if (mouseEvent->button() == Qt::MouseButton::LeftButton) if (m_status == CreateMask)
m_btn_pressed = 1;
else if (mouseEvent->button() == Qt::MouseButton::RightButton)
m_btn_pressed = 2;
if (m_status == CreateRect)
{ {
m_activeItem = addRect(QRectF(mouseEvent->scenePos(), QSize(1, 1)), QPen(m_brush.color()), m_brush); m_activeItem = addRect(QRectF(mouseEvent->scenePos(), QSize(1, 1)), QPen(m_brush.color()), m_brush);
m_startPoint = mouseEvent->scenePos(); 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) else if (m_status == CreateEllipse)
{ {
m_activeItem = addEllipse(QRectF(mouseEvent->scenePos(), QSize(1, 1)), m_pen, QBrush()); m_activeItem = addEllipse(QRectF(mouseEvent->scenePos(), QSize(1, 1)), m_pen, QBrush());
@ -308,30 +439,38 @@ void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
return; return;
} }
m_btn_pressed = 0;
if (m_activeItem != nullptr)
if (typeid(*m_activeItem) != typeid(QGraphicsProxyWidget))
m_activeItem = nullptr;
if (m_status == CreateText) if (m_status == CreateText)
{ {
if (m_activeItem != nullptr) if (m_activeItem != nullptr)
{ {
assert(typeid(*m_activeItem) == typeid(QGraphicsProxyWidget));
QRectF r(m_edit->mapToParent(QPoint()), m_edit->size()); QRectF r(m_edit->mapToParent(QPoint()), m_edit->size());
if (r.contains(mouseEvent->scenePos())) if (r.contains(mouseEvent->scenePos()))
{ {
QGraphicsScene::mouseReleaseEvent(mouseEvent); QGraphicsScene::mouseReleaseEvent(mouseEvent);
return; return;
} }
QString text = m_edit->document()->toPlainText(); QString text = m_edit->document()->toPlainText();
QFont font = m_edit->font(); QFont font = m_edit->font();
removeItem(m_activeItem); removeItem(m_activeItem);
m_activeItem = nullptr;
QGraphicsTextItem* item = addText(text, font); QGraphicsTextItem* item = addText(text, font);
item->setPos(m_edit->mapToParent(QPoint())); item->setPos(m_edit->mapToParent(QPoint()));
item->setDefaultTextColor(m_pen.color()); 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; delete m_edit;
m_edit = nullptr; m_edit = nullptr;
m_activeItem = nullptr; emit itemChanged();
} }
else else
{ {
@ -343,6 +482,23 @@ void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
m_activeItem = widget; m_activeItem = widget;
m_edit->setFocus(); 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();
}
} }
} }

View File

@ -3,8 +3,8 @@
#include <QGraphicsScene> #include <QGraphicsScene>
#include <QGraphicsPixmapItem> #include <QGraphicsPixmapItem>
#include <QTextEdit> #include <QTextEdit>
#include <vector>
class GraphicsTextEdit : public QTextEdit class GraphicsTextEdit : public QTextEdit
{ {
@ -29,6 +29,7 @@ public:
enum STATUS enum STATUS
{ {
Normal = 0, Normal = 0,
CreateMask,
CreateRect, CreateRect,
CreateEllipse, CreateEllipse,
CreateLine, CreateLine,
@ -41,6 +42,7 @@ public:
enum enum
{ {
None, None,
Mask,
Rect, Rect,
Ellipse, Ellipse,
Line, Line,
@ -61,8 +63,18 @@ public:
void setItemFlag(int flag); void setItemFlag(int flag);
void unDo(); bool isCanUndo();
void undo();
bool isCanRedo();
void redo();
void clear();
signals:
void itemChanged();
private: private:
void flush();
void updateShow();
QPainterPath createArrowPath(const QPointF& p1, const QPointF& p2); QPainterPath createArrowPath(const QPointF& p1, const QPointF& p2);
protected: protected:
@ -72,12 +84,13 @@ protected:
private: private:
STATUS m_status; STATUS m_status;
QGraphicsItem* m_activeItem; QGraphicsItem* m_activeItem;
int m_btn_pressed;
QPointF m_startPoint; QPointF m_startPoint;
QPen m_pen; QPen m_pen;
QBrush m_brush; QBrush m_brush;
QFont m_font; QFont m_font;
GraphicsTextEdit* m_edit; GraphicsTextEdit* m_edit;
std::vector<QGraphicsItem*> m_ItemList;
int m_curItemIndex;
}; };
#endif // GRAPHICSSCENE_H #endif // GRAPHICSSCENE_H