How to do it…

Let's start our fun project through the following steps:

  1. Again, we start by creating a new Qt Widgets Application project and removing the tool bar and status bar. We will keep the menu bar this time.
  2. After that, set up the menu bar like so:

  1. We will leave the menu bar as it is for the moment, so let's proceed to the mainwindow.h file. First, include the following header files, as they are required for the project:
#include <QPainter>
#include <QMouseEvent>
#include <QFileDialog>
  1. Next, declare the variables that we'll be using for this project, like so:
private:
Ui::MainWindow *ui;
QImage image;
bool drawing;
QPoint lastPoint;
int brushSize;
QColor brushColor;
  1. Then, declare the event callback functions, which are inherited from the QWidget class. These functions will be triggered by Qt when the respective event happens. We will override these functions and tell Qt what to do when these events get called:
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
virtual void paintEvent(QPaintEvent *event);
virtual void resizeEvent(QResizeEvent *event);
  1. After that, go to the mainwindow.cpp file and add the following code to the class constructor to set up some of the variables:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
image = QImage(this->size(), QImage::Format_RGB32);
image.fill(Qt::white);
drawing = false;
brushColor = Qt::black;
brushSize = 2;
}
  1. Next, we will construct the mousePressEvent() event and tell Qt what to do when the left mouse button is pressed:
void MainWindow::mousePressEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
drawing = true;
lastPoint = event->pos();
}
}
  1. Then, we will construct the mouseMoveEvent() event and tell Qt what to do when the mouse is moving. In this case, we want to draw the lines on the canvas if the left mouse button is being held:
void MainWindow::mouseMoveEvent(QMouseEvent *event) {
if ((event->buttons() & Qt::LeftButton) && drawing) {
QPainter painter(&image);
painter.setPen(QPen(brushColor, brushSize, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
painter.drawLine(lastPoint, event->pos());
lastPoint = event->pos();
this->update();
}
}
  1. After that, we will also construct the mouseReleaseEvent() event, which will be triggered when the mouse button is released:
void MainWindow::mouseReleaseEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
drawing = false;
}
}
  1. Once you're done with that, we will proceed to the paintEvent() event, which is surprisingly simple compared to the other examples we have seen in previous sections:
void MainWindow::paintEvent(QPaintEvent *event) {
QPainter canvasPainter(this);
canvasPainter.drawImage(this->rect(), image, image.rect());
}
  1. Remember how we have a menu bar sitting around doing nothing? Let's right-click on each of the actions below the GUI editor and select Go to slot… in the pop-up menu. We want to tell Qt what to do when each of these options on the menu bar is selected:

  1. Then, select the default slot called triggered() and press the OK button. Qt will automatically generate a new slot function in both your mainwindow.h and mainwindow.cpp files. Once you are done with all the actions, you should see something like this in your mainwindow.h file:
private slots:
void on_actionSave_triggered();
void on_actionClear_triggered();
void on_action2px_triggered();
void on_action5px_triggered();
void on_action10px_triggered();
void on_actionBlack_triggered();
void on_actionWhite_triggered();
void on_actionRed_triggered();
void on_actionGreen_triggered();
void on_actionBlue_triggered();
  1. Next, we will tell Qt what to do when each of these slots is triggered:
void MainWindow::on_actionSave_triggered() {
QString filePath = QFileDialog::getSaveFileName(this, "Save Image", "", "PNG (*.png);;JPEG (*.jpg *.jpeg);;All files (*.*)");
if (filePath == "")
return;
image.save(filePath);
}
void MainWindow::on_actionClear_triggered() {
image.fill(Qt::white);
this->update();
}
  1. Then, we continue to implement the other slots:
void MainWindow::on_action2px_triggered() {
brushSize = 2;
}
void MainWindow::on_action5px_triggered() {
brushSize = 5;
}
void MainWindow::on_action10px_triggered() {
brushSize = 10;
}
void MainWindow::on_actionBlack_triggered() {
brushColor = Qt::black;
}
  1. Finally, we implement the rest of the slot functions:
void MainWindow::on_actionWhite_triggered() {
brushColor = Qt::white;
}
void MainWindow::on_actionRed_triggered() {
brushColor = Qt::red;
}
void MainWindow::on_actionGreen_triggered() {
brushColor = Qt::green;
}
void MainWindow::on_actionBlue_triggered() {
brushColor = Qt::blue;
}
  1. If we compile and run the program now, we will get a simple but usable paint program:

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset