Qt 小画板
程序员文章站
2022-03-23 15:41:31
菜单栏的功能都实现了,如果想添加工具栏可以用函数封装代码放行使用mainWindow.h#ifndef MAINWINDOW_H#define MAINWINDOW_H#include #include #include #include #include #include #include...
菜单栏的功能都实现了,如果想添加工具栏可以用函数封装
代码放行使用
mainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QApplication>
#include <QMenu>
#include <QAction>
#include <QMenuBar>
#include <QDebug>
#include <QMouseEvent>
#include <QVector>
#include <QPainter>
#include <QPixmap>
#include <QDialog>
#include <QComboBox>
#include <QFileDialog>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
enum Number{
One = 1,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Ten
};
protected:
void paintEvent(QPaintEvent *event)override; // 重绘事件
void resizeEvent(QResizeEvent *size)override; // 窗口大小变动事件
void mousePressEvent(QMouseEvent *event)override; // 鼠标点击事件
void mouseMoveEvent(QMouseEvent *event)override; // 鼠标移动事件
void mouseReleaseEvent(QMouseEvent *event)override; // 鼠标弹起事件
private:
QMenu *menu;
QAction *action1;
QAction *action2;
QAction *action3;
QAction *action4;
QAction *action5;
QAction *action6;
QAction *action7;
QAction *action8;
QAction *action9;
QAction *actioncolor;
QPixmap pixmap;
QPixmap pix;
QPixmap null;
QPen pen;
QComboBox *comboBox;
QVector<QLine>line; // 直线
QVector<QLine>lines; // 铅笔
QVector<QVector<QLine>>vecline; // 记录铅笔移动的二维容器
QVector<QVector<QVector<QLine>>>myline; // 记录铅笔的三维容器
QVector<QRect>rect; // 椭圆
QVector<QRect>elli; // 矩形
QVector<int>vec; // 记录绘画的笔数
bool isMouse;
Number num;
Number tool;
QApplication *t; // 退出事件循环的对象指针
public slots:
void slotType(QAction *type);
void slotColor(int color);
};
#endif // MAINWINDOW_H
mainWindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
menu = menuBar()->addMenu(tr("绘图")); // 添加一个菜单栏
action1 = menu->addAction(tr("打开"),nullptr,nullptr,QKeySequence("Ctrl+O")); // 添加一个菜单
action2 = menu->addAction(tr("保存"),nullptr,nullptr,QKeySequence("Ctrl+S"));
action3 = menu->addAction(tr("铅笔"),nullptr,nullptr,QKeySequence("Ctrl+1"));
action4 = menu->addAction(tr("直线"),nullptr,nullptr,QKeySequence("Ctrl+2"));
action5 = menu->addAction(tr("椭圆"),nullptr,nullptr,QKeySequence("Ctrl+3"));
action6 = menu->addAction(tr("矩形"),nullptr,nullptr,QKeySequence("Ctrl+4"));
actioncolor = menu->addAction(tr("颜色"));
action7 = menu->addAction(tr("撤回"),nullptr,nullptr,QKeySequence("Ctrl+Z"));
action8 = menu->addAction(tr("清除"),nullptr,nullptr,QKeySequence("Ctrl+D"));
action9 = menu->addAction(tr("退出"),nullptr,nullptr,QKeySequence("Esc"));
QActionGroup *actiongroup = new QActionGroup(this);
actiongroup->addAction(action1); // 将动作存到Group中
actiongroup->addAction(action2);
actiongroup->addAction(action3);
actiongroup->addAction(action4);
actiongroup->addAction(action5);
actiongroup->addAction(action6);
actiongroup->addAction(actioncolor);
actiongroup->addAction(action7);
actiongroup->addAction(action8);
actiongroup->addAction(action9);
connect(actiongroup,SIGNAL(triggered(QAction *)),this,SLOT(slotType(QAction *)));
resize(this->width(),this->height());
pixmap = QPixmap(this->size());
pixmap.fill(Qt::white);
pix = QPixmap(this->size());
pix.fill(Qt::white);
null = QPixmap(this->size());
null.fill(Qt::white);
isMouse = false;
}
MainWindow::~MainWindow()
{
}
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
if(isMouse){
pix = pixmap; // 得到上次绘画的东西
QPainter pain(&pix);
pain.setPen(pen);
if(num == Three){
pain.drawLine(lines.back());
lines.back().setP1(lines.back().p2()); // 更新首节点
pixmap = pix; // 将每次绘画的初始点和末尾点赋给pixmap
}
else if(num == Four && isMouse){
pain.drawLine(line.back().p1(),line.back().p2());
}
else if(num == Five && isMouse){
pain.drawEllipse(elli.back());
}
else if(num == Six && isMouse){
pain.drawRect(rect.back());
}
}
if(!isMouse){
pixmap = pix;
QPainter pain(&pix);
pain.setPen(pen);
if(tool == Seven){
int linee=0,ellii=0,rectt=0;
for(int i=0;i<vec.length();i++){
if(vec[i] == Three){
for(int i=0;i<myline.length();i++){ // 进入外层 2
for(int j=0;j<myline.at(i).length();j++){ // 进入 vecline 层
for(int k=0;k<myline.at(i).at(j).length();k++){ // 进入lines 层
pain.drawLine(myline.at(i).at(j).at(k));
}
}
}
}
else if(vec[i] == Four){
pain.drawLine(line.at(linee).p1(),line.at(linee).p2());
linee++;
}
else if(vec[i] == Five){
pain.drawEllipse(elli.at(ellii));
ellii++;
}
else if(vec[i] == Six){
pain.drawRect(rect.at(rectt));
rectt++;
}
}
tool = Ten;
}
}
painter.drawPixmap(0,0,pix);
// painter.drawPixmap(610,0,pixmap);
}
void MainWindow::resizeEvent(QResizeEvent *size) // 当窗口大小变化更新画板
{
this->resize(size->size());
pixmap = QPixmap(size->size());
pixmap.fill(Qt::white);
pix = QPixmap(size->size());
pix.fill(Qt::white);
null = QPixmap(size->size());
null.fill(Qt::white);
}
void MainWindow::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton){
if(num == Three){ // 铅笔模式
QLine Lines(event->pos(),QPoint(0,0));
lines.append(Lines); // 记录点击的第一笔
vec.append(Three); // 添加那个模式点击的画笔
isMouse = true; // 开启绘画锁
}
else if(num == Four){ // 直线模式
QLine Line(event->pos(),QPoint(0,0));
line.append(Line);
vec.append(Four);
isMouse = true;
}
else if(num == Five){ // 椭圆模式
QRect Elli(event->pos(),QPoint(0,0));
elli.append(Elli);
vec.append(Five);
isMouse = true;
}
else if(num == Six){ // 矩形模式
QRect Rect(event->pos(),QPoint(0,0));
rect.append(Rect);
vec.append(Six);
isMouse = true;
}
}
else if(event->button() == Qt::RightButton){ // 右击菜单栏
menu->exec(cursor().pos());
}
}
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
if(!isMouse)
return;
if(event->buttons() == Qt::LeftButton){
if(num == Three){ // 铅笔移动模式
lines.back().setP2(event->pos()); // 设置点p2 的坐标为移动的坐标
vecline.append(lines); // 记录移动的两点 坐标
update();
}
else if(num == Four){ // 直线移动模式
line.back().setP2(event->pos());
update();
}
else if(num == Five){ // 椭圆移动模式
elli.back().setBottomRight(event->pos());
update();
}
else if(num == Six){ // 矩形移动模式
rect.back().setBottomRight(event->pos());
update();
}
}
}
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
if(!isMouse)
return;
if(event->button() == Qt::LeftButton){
if(num == Three){ // 弹起铅笔模式
lines.back().setP2(event->pos()); // 更新一次释放点的坐标
myline.append(vecline); // 将上面移动的记录存到 三维容器中
QVector<QVector<QLine>>vecnullptr;
vecline = vecnullptr; // 清空上一次 的vecline 记录的移动项
update();
}
else if(num == Four){ // 弹起直线模式
line.back().setP2(event->pos());
update();
}
else if(num == Five){ // 弹起椭圆模式
elli.back().setBottomRight(event->pos());
update();
}
else if(num == Six){ // 弹起矩形模式
rect.back().setBottomRight(event->pos());
update();
}
isMouse = false; // 关闭绘画锁
}
}
void MainWindow::slotType(QAction *type) // 触发点击的哪一个动作的槽函数 如果添加工具栏的话可以用函数封装下就行
{
if(type == action1){ // 打开
QString filename = QFileDialog::getOpenFileName(this,tr("打开文件"),"/","Image(*.png);;Image(*.jpg)");
if(filename.isEmpty())
return;
QPixmap pixopen(filename);
QPainter p(&pix);
p.drawPixmap(0,0,pixopen);
update();
}
else if(type == action2){ // 保存
QString filename = QFileDialog::getSaveFileName(this,tr("保存文件"),"image.png","Image(*.png);;Image(*.jpg)");
if(filename.isEmpty())
return;
pix.save(filename);
}
else if(type == action3){ // 铅笔
num = Three;
}
else if(type == action4){ // 直线
num = Four;
}
else if(type == action5){ // 椭圆
num = Five;
}
else if(type == action6){ // 矩形
num = Six;
}
else if(type == actioncolor){
QDialog w;
comboBox = new QComboBox(&w);
QPixmap compix(16,16);
QPainter painter(&compix);
painter.fillRect(0,0,16,16,Qt::black);
comboBox->addItem(QIcon(compix),tr("黑色"));
painter.fillRect(0,0,16,16,Qt::white);
comboBox->addItem(QIcon(compix),tr("白色"));
painter.fillRect(0,0,16,16,Qt::red);
comboBox->addItem(QIcon(compix),tr("红色"));
painter.fillRect(0,0,16,16,Qt::blue);
comboBox->addItem(QIcon(compix),tr("蓝色"));
painter.fillRect(0,0,16,16,Qt::green);
comboBox->addItem(QIcon(compix),tr("绿色"));
painter.fillRect(0,0,16,16,Qt::yellow);
comboBox->addItem(QIcon(compix),tr("黄色"));
connect(comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(slotColor(int)));
w.exec();
}
else if(type == action7){ // 撤回
if(vec.isEmpty())
return;
if(vec.back() == Three){
myline.pop_back();
}
else if(vec.back() == Four){
line.pop_back();
}
else if(vec.back() == Five){
elli.pop_back();
}
else if(vec.back() == Six){
rect.pop_back();
}
vec.pop_back();
pix = null;
pixmap = null;
tool = Seven;
update();
}
else if(type == action8){ // 清除
pix = null;
pixmap = null;
tool = Eight;
update();
}
else if(type == action9){ // 退出
t->quit();
}
}
void MainWindow::slotColor(int color)
{
switch (color) {
case 0:pen.setColor(Qt::black); break;
case 1:pen.setColor(Qt::white); break;
case 2:pen.setColor(Qt::red); break;
case 3:pen.setColor(Qt::blue); break;
case 4:pen.setColor(Qt::green); break;
case 5:pen.setColor(Qt::yellow);break;
}
}
main.cpp
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
本文地址:https://blog.csdn.net/qq_44698445/article/details/107347256