Simple drawing software based on qt under linux

In class today, I made a drawing software through qt under the linux platform. The steps of the drawing software are as follows:

1. Create a new all-white image (I will open a image as an example below)

2. By getting the position of the mouse, click and then modify the color of the corresponding pixel

3. Save the picture (time is limited, this part is not finished)


Next, let's talk about how to make this small program

1. Open the linux virtual machine and create a new project file in qt


2. Set up the ui interface, I am very simple here, just a label and a pushbutton


3. After the interface design is completed, it is time to start doing some functional things. In qt, set the slot function. At this time, my idea is to click the button, and then the file selection box will pop up, select the desired image, and select the format filter For jpg and png, so just click the pushbutton, add the slot function, and add the following code in clicked():

void MainWindow::on_pushButton_clicked()
{
    /*QFileDialog return String value,so declare String filename in mainwindow.h*/
    filename=QFileDialog::getOpenFileName(this,tr("Open Image"),"/home/exbot/123",tr("Image Files(*.jpg *.png)"));
    
    /*loading the filename to image*/
    image.load(filename);   //direct to load image and do not create the mix variable pPixmap
    
    /*show the pic of filename or a complete path instead it*/
    ui->label->setPixmap(QPixmap(filename));
    
   // ui->label->setGeometry(ui->label->pos().rx(),ui->label->pos().ry(),image.width(),image.height());
    
    /*let the pic of the head match the label of the position (0,0)*/
    ui->label->setGeometry(ui->label->geometry().topLeft().x(),ui->label->geometry().topLeft().y(),image.width(),image.height());
    ui->label->setScaledContents(true);
}

4. After the previous step is completed, you can click the button, and then a selection box will pop up. The default path is the /home/exbot/123 directory. Well, now we can select and open the picture, then the next step is to figure out how to click the mouse, and then have the function of the brush (modify the pixels). To achieve this function, you need to use the mouseMoveEvent function, which you have to type by yourself. There is no button right-clicking the slot function and then automatically generating it (a bit troublesome - - ), the following gives all the code of the mouseMoveEvent function, and then explain what it means one by one (the program is completed I'm too lazy to unpack the code to write documentation - - )

void MainWindow::mouseMoveEvent(QMouseEvent *e)
{
    static int times=0; //Number of mouse sliding events
    times++; //Press and hold the mouse and slide, the number of times keeps increasing
    //qDebug()<<"mouse move"<<times<<e->x()<<e->y(); //Print the number of mouse slides and the (x, y) coordinates of the mouse
     qDebug()<<"label pos "<<ui->label->geometry().topLeft().x()<<ui->label->geometry().topLeft().y(); // Print the coordinate position of the upper left corner of the label

   // image=QPixmap(filename).toImage();
    unsigned char *data;
    data=image.bits();
    int Width=image.width();
    int Height=image.height();
  //  memset(data,0xFF,times*1000);

    int labelX=ui->label->geometry().topLeft().x();
    int labelY=ui->label->geometry().topLeft().y(); //The horizontal and vertical coordinates of the upper left corner of the label

    int image_width=image.width();
    int image_height=image.height(); //The length and width of the image

    int label_width=ui->label->width();
    int label_height=ui->label->height(); //label length and width



    double Yrate=(double)image_height/(double)label_height;
    double Xrate=(double)image_width/(double)label_width; //Calculate the ratio of the length and width of the image to the length and width of the label (used to realize the drawing effect after screen adaptation)

    int targetX=(int)((double)(e->x() - labelX))*Xrate;
    int targetY=(int)((double)(e->y() - labelY-15))*Yrate; //Determine the coordinates of the point to be drawn by the mouse

    int border_bottomRightX=ui->label->geometry().bottomRight().x();
    int border_bottomRightY=ui->label->geometry().bottomRight().y();
    int border_topleftX=ui->label->geometry().topLeft().x();
    int border_topleftY=ui->label->geometry().topRight().y(); //These 4 statements are actually the border of the picture

   // if(e->x()<border_bottomRightX&&e->y()<border_bottomRightY&&e->x()>border_topleftX&&e->y()>border_topleftY)

            for(int i=targetY;i<targetY+5;i++) // Through this loop, the value of the pixel clicked by the mouse can be modified, which is set to all 255 (white)
            {
                for(int j=targetX;j<targetX+5;j++)
                {
                    *(data+RGB_32*(i*Width+j))=255;
                    *(data+RGB_32*(i*Width+j)+1)=255;
                    *(data+RGB_32*(i*Width+j)+2)=255;
                }
            }


    /*
    for(int i=e->y()-13;i<e->y();i++) //The same effect as the above loop
    {
        for(int j=e->x();j<e->x()+5;j++)
        {
            *(data+RGB_32*(i*Width+j))=255;
            *(data+RGB_32*(i*Width+j)+1)=255;
            *(data+RGB_32*(i*Width+j)+2)=255;
        }
    }
    */
    QPixmap ConvertPixmap=QPixmap::fromImage(image); //Convert image back to pixmap form
    ui->label->setPixmap(ConvertPixmap); //Display picture
}

The above is all the code. Some of the test code has not been deleted. You can use it to test and verify the function of some code.

5. Give the code of all files for reference

(1)mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QFileDialog>
#include<QDebug>
#include<QMouseEvent>
#include<QWidget>
#include<QPaintEvent>
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~ MainWindow ();
    QString filename;
    QImage image;

private slots:
    void on_pushButton_clicked();
    void mouseMoveEvent(QMouseEvent *e);

private:
    Ui :: MainWindow * ui;
};

#endif // MAINWINDOW_H

(2)mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#define RGB_32 4
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui-> setupUi (this);
    ui->label->setText("");


}
MainWindow :: ~ MainWindow ()
{
    delete ui;
}



void MainWindow::on_pushButton_clicked()
{
    /*QFileDialog return String value,so declare String filename in mainwindow.h*/
    filename=QFileDialog::getOpenFileName(this,tr("Open Image"),"/home/exbot/123",tr("Image Files(*.jpg *.png)"));
    
    /*loading the filename to image*/
    image.load(filename);   //direct to load image and do not create the mix variable pPixmap
    
    /*show the pic of filename or a complete path instead it*/
    ui->label->setPixmap(QPixmap(filename));
    
   // ui->label->setGeometry(ui->label->pos().rx(),ui->label->pos().ry(),image.width(),image.height());
    
    /*let the pic of the head match the label of the position (0,0)*/
    ui->label->setGeometry(ui->label->geometry().topLeft().x(),ui->label->geometry().topLeft().y(),image.width(),image.height());
    ui->label->setScaledContents(true);
}

void MainWindow::mouseMoveEvent(QMouseEvent *e)
{
    static int times=0;
    times++;
    //qDebug()<<"mouse move"<<times<<e->x()<<e->y();
       qDebug()<<"label pos "<<ui->label->geometry().topLeft().x()<<ui->label->geometry().topLeft().y();

   // image=QPixmap(filename).toImage();
    unsigned char *data;
    data=image.bits();
    int Width=image.width();
    int Height=image.height();
  //  memset(data,0xFF,times*1000);

    int labelX=ui->label->geometry().topLeft().x();
    int labelY=ui->label->geometry().topLeft().y();

    int image_width=image.width();
    int image_height=image.height();

    int label_width=ui->label->width();
    int label_height=ui->label->height();



    double Yrate=(double)image_height/(double)label_height;
    double Xrate=(double)image_width/(double)label_width;

    int targetX=(int)((double)(e->x() - labelX))*Xrate;
    int targetY=(int)((double)(e->y() - labelY-15))*Yrate;

    int border_bottomRightX=ui->label->geometry().bottomRight().x();
    int border_bottomRightY=ui->label->geometry().bottomRight().y();
    int border_topleftX=ui->label->geometry().topLeft().x();
    int border_topleftY=ui->label->geometry().topRight().y();

   // if(e->x()<border_bottomRightX&&e->y()<border_bottomRightY&&e->x()>border_topleftX&&e->y()>border_topleftY)

            for(int i=targetY;i<targetY+5;i++)
            {
                for(int j=targetX;j<targetX+5;j++)
                {
                    *(data+RGB_32*(i*Width+j))=255;
                    *(data+RGB_32*(i*Width+j)+1)=255;
                    *(data+RGB_32*(i*Width+j)+2)=255;
                }
            }


    /*
    for(int i=e->y()-13;i<e->y();i++)
    {
        for(int j=e->x();j<e->x()+5;j++)
        {
            *(data+RGB_32*(i*Width+j))=255;
            *(data+RGB_32*(i*Width+j)+1)=255;
            *(data+RGB_32*(i*Width+j)+2)=255;
        }
    }
    */
    QPixmap ConvertPixmap=QPixmap::fromImage(image);
    ui->label->setPixmap(ConvertPixmap);
}

6. The operation effect is as follows







Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325208904&siteId=291194637