C++QT SeriesHand-rubbing software – cut picture monster

Since I also like war3 game development, I need to “borrow” other people’s art icons in many cases, and the downloaded integrated icons need to be cut out in grid format, so I searched online if there is such a software for custom grid cutting pictures. But it is a pity that the software on the Internet either has unknown functions or does not meet the ideal way of use. At that moment, the seed of “the whole one” germinated in my heart. From the UI layout design of the software to the function production, although the function is single, in the end it ~ “Cutting Monster” was born! ! ! Of course, the icon is also “borrowed”, a software that can cut pictures in a custom grid format, small but powerful! The following is the software download and source code sharing
Link: Cutout Monster Download
Extraction code: lz88
Software initial state
software open picture
software cropping

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QVector>
#include <QPixmap>
#include <QLineEdit>
#include <QScrollBar>
#include <QWheelEvent>
#include <QFileDialog>
#include <QPushButton>
#include <QIntValidator>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsItem>
#include <QGraphicsEffect>

class GraphicsView : public QGraphicsView{<!-- -->
public:
    GraphicsView(QGraphicsView* parent = nullptr);
    GraphicsView(QGraphicsScene* scene, QWidget* parent = nullptr);
    ~GraphicsView();
    void wheelEvent(QWheelEvent* event);//The zoom function of the window needs to rewrite the virtual function of the window
};
class Widget : public QWidget{<!-- -->
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private:
    //all buttons
    QPushButton* btnOpenImage;
    QPushButton* btnCropInitX;
    QPushButton* btnCropInitY;
    QPushButton* btnCropRow;
    QPushButton* btnCropCol;
    QPushButton* btnCropWidth;
    QPushButton* btnCropHeight;
    QPushButton* btnCropSpaceX;
    QPushButton* btnCropSpaceY;
    QPushButton* btnResetValue;
    QPushButton* btnCrop;
    //all input boxes
    QLineEdit* eitCropInitX;
    QLineEdit* eitCropInitY;
    QLineEdit* eitCropRow;
    QLineEdit* eitCropCol;
    QLineEdit* eitCropWidth;
    QLineEdit* eitCropHeight;
    QLineEdit* eitCropSpaceX;
    QLineEdit* eitCropSpaceY;
    //Save pointers to all trim boxes
    QVector<QGraphicsRectItem*> vecCropRect;

    QPixmap* mapImage;
    QGraphicsScene* scene;//Scene
    GraphicsView* view;//window
    QGraphicsPixmapItem* pixmap;//element
    QGraphicsDropShadowEffect* efeButtonShadow[11];//Shadow of all buttons

    void resizeEvent(QResizeEvent* event);//Rewrite the virtual function of widget size scaling
    void CreateCropRect();//Create a trim box for the first time
    void UpdateCropRect();//Update crop box
    void SetButtonAttribute(QPushButton & amp; btn, QString name, QFont & amp; font, const int & amp; fontSize, const int & amp; x, const int & amp; y, const int & amp; width, const int & amp ;height,
                            QString & amp; styleSheet, QGraphicsDropShadowEffect* efeShadow);//Set button properties
    void SetEditAttribute(QLineEdit & amp; edit, QString name, QFont & amp; font, const int & amp; fontSize, const int & amp; x, const int & amp; y, const int & amp; width, const int & amp ;height,
                          QIntValidator & amp; validator, QFlags<Qt::AlignmentFlag> flag, QString & amp; styleSheet);//Set input box properties
private slots:
    void ActionButtonClick(bool);//button trigger event
    void ActionEditChanged(const QString & amp;);//Input box triggers event
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"

GraphicsView::GraphicsView(QGraphicsView* parent)
    : QGraphicsView(parent){<!-- -->}
GraphicsView::GraphicsView(QGraphicsScene* scene, QWidget* parent)
    : QGraphicsView(scene, parent){<!-- -->}
GraphicsView::~GraphicsView(){<!-- -->}
Widget::Widget(QWidget *parent)
    : QWidget(parent){<!-- -->
    resize(800, 600);//Set the initial size of the software
    setMinimumSize(800, 600);//Set the latest size of the software
    setWindowTitle("cutting monster");//Set the name
    setWindowIcon(QIcon("://icon.ico"));//Set icon

    QFont font("Microsoft Yahei");
    font.setBold(true);
    for(int i = 0; i < 11; i ++ ){<!-- -->
        efeButtonShadow[i] = new QGraphicsDropShadowEffect(this);
        efeButtonShadow[i]->setOffset(0, 0);
        efeButtonShadow[i]->setBlurRadius(8);
        efeButtonShadow[i]->setColor(QColor(44, 44, 44, 210));
    }//Set properties for the shadow
    QIntValidator validator(0, 999, this);//Set the range of numbers in the input box
    QString strButtonStyleSheet = "QPushButton{"
                                  "background-color: rgb(54,98,236);"
                                  "color:rgb(255,255,255);"
                                  "border-radius:10px;"
                                  "border:none;"
                                  "text-align: center;"
                                  " padding: 0px;"
                                  "}"
                                  "QPushButton::hover{"
                                  "background-color: rgb(64,108,236);"
                                  "}"
                                  "QPushButton::pressed{"
                                  "background-color: rgb(44,88,236);"
                                  "}";//Button style
    QString strEditStyleSheet = "QLineEdit{"
                                "background-color: rgb(255,255,255);"
                                "color:rgb(0,0,0);"
                                "border:none;"
                                "border-radius:10px;"
                                "}";//input box style
    btnOpenImage = new QPushButton(this);
    btnCropInitX = new QPushButton(this);
    btnCropInitY = new QPushButton(this);
    btnCropWidth = new QPushButton(this);
    btnCropHeight = new QPushButton(this);
    btnCropRow = new QPushButton(this);
    btnCropCol = new QPushButton(this);
    btnCropSpaceX = new QPushButton(this);
    btnCropSpaceY = new QPushButton(this);
    btnResetValue = new QPushButton(this);
    btnCrop = new QPushButton(this);

    eitCropInitX = new QLineEdit(this);
    eitCropInitY = new QLineEdit(this);
    eitCropWidth = new QLineEdit(this);
    eitCropHeight = new QLineEdit(this);
    eitCropRow = new QLineEdit(this);
    eitCropCol = new QLineEdit(this);
    eitCropSpaceX = new QLineEdit(this);
    eitCropSpaceY = new QLineEdit(this);
    //Set button properties
    SetButtonAttribute(*btnOpenImage, "Open image", font, 18, 20, 20, 190, 90, strButtonStyleSheet, efeButtonShadow[0]);
    SetButtonAttribute(*btnCropInitX, "Initial coordinate X", font, 10, 90, 130, 80, 30, strButtonStyleSheet, efeButtonShadow[1]);
    SetButtonAttribute(*btnCropInitY, "Initial coordinate Y", font, 0, 90, 170, 80, 30, strButtonStyleSheet, efeButtonShadow[2]);
    SetButtonAttribute(*btnCropWidth, "long", font, 0, 20, 210, 50, 30, strButtonStyleSheet, efeButtonShadow[3]);
    SetButtonAttribute(*btnCropHeight, "Width", font, 0, 120, 210, 50, 30, strButtonStyleSheet, efeButtonShadow[4]);
    SetButtonAttribute(*btnCropRow, "number of rows", font, 0, 20, 250, 50, 30, strButtonStyleSheet, efeButtonShadow[5]);
    SetButtonAttribute(*btnCropCol, "Number of columns", font, 0, 120, 250, 50, 30, strButtonStyleSheet, efeButtonShadow[6]);
    SetButtonAttribute(*btnCropSpaceX, "Space X", font, 0, 20, 290, 50, 30, strButtonStyleSheet, efeButtonShadow[7]);
    SetButtonAttribute(*btnCropSpaceY, "Space Y", font, 0, 120, 290, 50, 30, strButtonStyleSheet, efeButtonShadow[8]);
    SetButtonAttribute(*btnResetValue, "Reset All", font, 0, 130, 330, 80, 30, strButtonStyleSheet, efeButtonShadow[9]);
    SetButtonAttribute(*btnCrop, "Crop", font, 18, 20, 500, 190, 90, strButtonStyleSheet, efeButtonShadow[10]);
    //Set the input box properties
    SetEditAttribute(*eitCropInitX, "0", font, 10, 180, 130, 30, 30, validator, Qt::AlignCenter, strEditStyleSheet);
    SetEditAttribute(*eitCropInitY, "0", font, 0, 180, 170, 30, 30, validator, Qt::AlignCenter, strEditStyleSheet);
    SetEditAttribute(*eitCropWidth, "64", font, 0, 80, 210, 30, 30, validator, Qt::AlignCenter, strEditStyleSheet);
    SetEditAttribute(*eitCropHeight, "64", font, 0, 180, 210, 30, 30, validator, Qt::AlignCenter, strEditStyleSheet);
    SetEditAttribute(*eitCropRow, "1", font, 0, 80, 250, 30, 30, validator, Qt::AlignCenter, strEditStyleSheet);
    SetEditAttribute(*eitCropCol, "1", font, 0, 180, 250, 30, 30, validator, Qt::AlignCenter, strEditStyleSheet);
    SetEditAttribute(*eitCropSpaceX, "0", font, 0, 80, 290, 30, 30, validator, Qt::AlignCenter, strEditStyleSheet);
    SetEditAttribute(*eitCropSpaceY, "0", font, 0, 180, 290, 30, 30, validator, Qt::AlignCenter, strEditStyleSheet);

    mapImage = new QPixmap;
    //Set the background of the scene to repeated horizontal and vertical lines to achieve a grid background effect
    QPixmap pix(20, 20);
    pix.fill(Qt::transparent);
    QPainter painter( & amp;pix);
    painter.setPen(QPen(QColor(44, 44, 44, 30), 1));
    painter.setBrush(Qt::NoBrush);
    painter. drawLine(0, 0, 0, 20);
    painter. drawLine(0, 0, 20, 0);
    //Create scene and viewport and add elements
    scene = new QGraphicsScene(this);
    scene->setBackgroundBrush(QBrush(pix));
    view = new GraphicsView(scene, this);
    view->setDragMode(QGraphicsView::ScrollHandDrag);
    view->setInteractive(false);
    view->setGeometry(230, 0, this->width() - 230, this->height());
    pixmap = new QGraphicsPixmapItem;
    pixmap->setFlag(QGraphicsItem::ItemIsMovable, true);
    scene->addItem(pixmap);
}
Widget::~Widget(){<!-- -->}
void Widget::ActionButtonClick(bool){<!-- -->
    QPushButton* btn = dynamic_cast<QPushButton*>(sender());
    if(btn == btnOpenImage){<!-- -->
        QString fileName = QFileDialog::getOpenFileName(this, "Open Image", "", "Images(*.png *.jpg)");
        if(!fileName.isEmpty()){<!-- -->
            mapImage->load(fileName);
            pixmap->setPixmap(*mapImage);
            CreateCropRect();
        }
    }else if(btn == btnCropInitX){<!-- -->
        eitCropInitX->setText("0");
    }else if(btn == btnCropInitY){<!-- -->
        eitCropInitY->setText("0");
    }else if(btn == btnCropWidth){<!-- -->
        eitCropWidth->setText("64");
    }else if(btn == btnCropHeight){<!-- -->
        eitCropHeight->setText("64");
    }else if(btn == btnCropRow){<!-- -->
        eitCropRow->setText("1");
    }else if(btn == btnCropCol){<!-- -->
        eitCropCol->setText("1");
    }else if(btn == btnCropSpaceX){<!-- -->
        eitCropSpaceX->setText("0");
    }else if(btn == btnCropSpaceY){<!-- -->
        eitCropSpaceY->setText("0");
    }else if(btn == btnResetValue){<!-- -->
        eitCropInitX->setText("0");
        eitCropInitY->setText("0");
        eitCropWidth->setText("64");
        eitCropHeight->setText("64");
        eitCropRow->setText("1");
        eitCropCol->setText("1");
        eitCropSpaceX->setText("0");
        eitCropSpaceY->setText("0");
    }else if(btn == btnCrop){<!-- -->
        if(!mapImage->isNull()){<!-- -->
            QString savePath = QFileDialog::getSaveFileName(this, "Save image", "", "PNG(*.png);;JPG(*.jpg)");
            if(!savePath.isEmpty()){<!-- -->
                QByteArray saveFormat = QFileInfo(savePath).suffix().toUpper().toLatin1();
                savePath. chop(4);
                int id = 0;
                for(int i = 0; i < eitCropCol->text().toInt(); i ++ ){<!-- -->
                    for(int j = 0; j < eitCropRow->text().toInt(); j++ ){<!-- -->
                        QPixmap pix = mapImage->copy(eitCropInitX->text().toInt() + j * (eitCropWidth->text().toInt() + eitCropSpaceX->text().toInt()),
                                                     eitCropInitY->text().toInt() + i * (eitCropHeight->text().toInt() + eitCropSpaceY->text().toInt()),
                                                     eitCropWidth->text().toInt(), eitCropHeight->text().toInt());
                        pix.save(savePath + "_" + QString::number(id) + "." + saveFormat, saveFormat);
                        id + + ;
                    }
                }
            }
        }
    }
}
void Widget::ActionEditChanged(const QString & amp;){<!-- -->
    if((eitCropWidth->text() != "0") & amp; & amp; (eitCropHeight->text() != "0")){<!-- -->
        UpdateCropRect();//Every time the value of the input box is modified, the crop box will be refreshed
    }
}
void Widget::resizeEvent(QResizeEvent* event){<!-- -->
    view->setGeometry(230, 0, this->width() - 230, this->height());//The coordinates and size of the window will be reset whenever the software size changes
    QWidget::resizeEvent(event);
}
void GraphicsView::wheelEvent(QWheelEvent *event){<!-- -->
    if (event->modifiers() == Qt::ControlModifier) {<!-- -->
        double scale = 1.05;//Set the zoom factor
        if (event->delta() < 0) {<!-- -->
            scale = 1 / scale;
        }
        QPointF viewPos = mapToScene(event->pos());
        this->scale(scale, scale);
        QPointF newViewPos = mapFromScene(viewPos);
        QPointF delta = newViewPos - event->pos();
        horizontalScrollBar()->setValue(horizontalScrollBar()->value() + delta.x());
        verticalScrollBar()->setValue(verticalScrollBar()->value() + delta.y());
    }//When pressing ctrl + scroll wheel, the window will be zoomed
    else{<!-- -->
        QGraphicsView::wheelEvent(event);
    }
}
void Widget::CreateCropRect(){<!-- -->
    if(eitCropWidth->text() != "0" & amp; & amp; eitCropHeight->text() != "0" & amp; & amp; eitCropRow->text() != "0" & amp; & amp; eitCropCol->text() != "0"){<!-- -->
        for(int i = 0; i < eitCropRow->text().toInt(); i ++ ){<!-- -->
            for(int j = 0; j < eitCropCol->text().toInt(); j++ ){<!-- -->
                QGraphicsRectItem* item = new QGraphicsRectItem;
                item->setPen(QPen(QColor(255, 0, 0), 1));
                vecCropRect.append(item);
                item->setRect(eitCropInitX->text().toInt() + j * (eitCropWidth->text().toInt() + eitCropSpaceX->text().toInt()),
                              eitCropInitY->text().toInt() + i * (eitCropHeight->text().toInt() + eitCropSpaceY->text().toInt()),
                              eitCropWidth->text().toInt(), eitCropHeight->text().toInt());
                scene->addItem(item);
            }
        }
    }
}
void Widget::UpdateCropRect(){<!-- -->
    if(!mapImage->isNull() & amp; & amp; eitCropWidth->text() != "0" & amp; & amp; eitCropHeight->text() != "0" & amp; & amp; eitCropRow ->text() != "0" & amp; & amp; eitCropCol->text() != "0"){<!-- -->
        qDeleteAll(vecCropRect);
        vecCropRect. clear();
        for(QVector<QGraphicsRectItem*>::iterator i = vecCropRect.begin(); i != vecCropRect.end(); i + + ){<!-- -->
            scene->removeItem(*i);
        }
        for(int i = 0; i < eitCropRow->text().toInt(); i ++ ){<!-- -->
            for(int j = 0; j < eitCropCol->text().toInt(); j++ ){<!-- -->
                QGraphicsRectItem* item = new QGraphicsRectItem;
                item->setPen(QPen(QColor(255, 0, 0), 1));
                vecCropRect.append(item);
                item->setRect(eitCropInitX->text().toInt() + j * (eitCropWidth->text().toInt() + eitCropSpaceX->text().toInt()),
                              eitCropInitY->text().toInt() + i * (eitCropHeight->text().toInt() + eitCropSpaceY->text().toInt()),
                              eitCropWidth->text().toInt(), eitCropHeight->text().toInt());
                scene->addItem(item);
            }
        }
    }
}
void Widget::SetButtonAttribute(QPushButton & amp; btn, QString name, QFont & amp; font, const int & amp; fontSize, const int & amp; x, const int & amp; y, const int & amp; width, const int & height,
                                QString & amp; styleSheet, QGraphicsDropShadowEffect* efeShadow){<!-- -->
    btn.setText(name);
    if(fontSize != 0){<!-- -->
        font.setPointSize(fontSize);
    }
    btn. setFont(font);
    btn. setGeometry(x, y, width, height);
    btn.setStyleSheet(styleSheet);
    btn.setGraphicsEffect(efeShadow);
    connect( & btn, SIGNAL(clicked(bool)), this, SLOT(ActionButtonClick(bool)));
}
void Widget::SetEditAttribute(QLineEdit & amp; edit, QString name, QFont & amp; font, const int & amp; fontSize, const int & amp; x, const int & amp; y, const int & amp; width, const int & height,
                              QIntValidator & amp; validator, QFlags<Qt::AlignmentFlag> flag, QString & amp; styleSheet){<!-- -->
    edit.setText(name);
    if(fontSize != 0){<!-- -->
        font.setPointSize(fontSize);
    }
    edit. setFont(font);
    edit.setMaxLength(4);
    edit.setValidator( & amp; validator);
    edit. setAlignment(flag);
    edit. setGeometry(x, y, width, height);
    edit.setStyleSheet(styleSheet);
    connect( & amp;edit, SIGNAL(textChanged(const QString & amp;)), this, SLOT(ActionEditChanged(const QString & amp;)));
}

Main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[]){<!-- -->
    QApplication a(argc, argv);
    Widget w;
    w. show();
    return a.exec();
}