作業
代碼
Widtget.h
class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;/************************ 起始終止坐標 ************************/QPoint end;QPoint start;QVector<QPoint> per_start_list; //容器 記錄每一次鼠標按下的start/************************ 畫筆相關 ************************/QPainter painter; //繪畫QPen pen; //畫筆/************************ 移動軌跡line ************************/struct line_attr{QLine line; //線長QColor color = Qt::black; //顏色int width = 1; //粗細}line_attr_temp; //line屬性bool rubber_in_use=0; //橡皮擦標志位:0未用 1使用QVector<line_attr> lines_attr; //容器 記錄每一個move時 line的屬性protected:virtual void paintEvent(QPaintEvent *event) override;virtual void mouseMoveEvent(QMouseEvent *event) override;virtual void mousePressEvent(QMouseEvent *event) override;virtual void mouseReleaseEvent(QMouseEvent *event) override;virtual void keyPressEvent(QKeyEvent *event) override;
private slots:void on_pushButton_clicked();void on_pushButton_2_clicked();void on_pushButton_3_clicked();void on_pushButton_4_clicked();void on_pushButton_5_clicked();
};
#endif // WIDGET_H
Widget.cpp
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}/**************** 繪畫邏輯 ****************/
void Widget::paintEvent(QPaintEvent *event)
{painter.begin(this);for(auto perline:lines_attr){pen.setColor(perline.color);pen.setWidth(perline.width);painter.setPen(pen);painter.drawLine(perline.line);}painter.end();
}/**************** 鼠標邏輯 ****************/
void Widget::mouseMoveEvent(QMouseEvent *event)
{end = event->pos(); //獲取鼠標最后位置QLine line(start,end); //生成小lineline_attr_temp.line = line; //結構體line成員屬性//置此,line_attr_temp所有屬性獲取完畢lines_attr.append(line_attr_temp); //放到容器start = end; //更新startupdate();
}void Widget::mousePressEvent(QMouseEvent *event)
{start = event->pos();per_start_list << start;
}void Widget::mouseReleaseEvent(QMouseEvent *event)
{end = event->pos();// 檢查:如果鼠標沒有移動if(per_start_list.last()==end){//則刪除剛剛 鼠標按下 時記錄的startper_start_list.removeLast();}
}
/*
錯誤現象:畫線后,空點一次,再使用撤銷,會出現段錯誤
錯誤原因:空點時,起始坐標start 放入容器中,但是沒有產生線段,撤銷時的判斷 "" 永遠無法達到,會一直刪除最后一個,直到段錯誤
錯誤解決:如果空點,即 "start==end" 則不寫入容器
特殊情況?如果沒有空點,但是移動后 "start==end" ????
*//**************** 畫筆顏色 ****************/
// 打開調色板
void Widget::on_pushButton_clicked()
{line_attr_temp.color = QColorDialog::getColor(Qt::black,this,"選擇顏色");
}/**************** 畫筆粗細 ****************/
void Widget::on_pushButton_2_clicked()
{line_attr_temp.width=1;
}void Widget::on_pushButton_3_clicked()
{line_attr_temp.width=5;
}void Widget::on_pushButton_4_clicked()
{line_attr_temp.width=10;
}/**************** 橡皮擦邏輯 ****************/
void Widget::on_pushButton_5_clicked()
{//備份當前畫筆屬性static struct line_attr line_attr_temp_backup = line_attr_temp;//切換橡皮擦狀態rubber_in_use=!rubber_in_use;if(rubber_in_use){//更改橡皮擦文本ui->pushButton_5->setText("使用中");//設置橡皮擦畫筆line_attr_temp.color = this->palette().color(QPalette::Background);qDebug() << "北京顏色" << this->palette().color(QPalette::Background);line_attr_temp.width = 30;//其他操作ui->pushButton->setEnabled(0); //使調色板失效ui->pushButton_2->setEnabled(0); //使畫筆粗細失效ui->pushButton_3->setEnabled(0);ui->pushButton_4->setEnabled(0);}else{//按鈕文本描述ui->pushButton_5->setText("Erasers");//恢復畫筆屬性line_attr_temp=line_attr_temp_backup;//其他操作ui->pushButton->setEnabled(1);ui->pushButton_2->setEnabled(1);ui->pushButton_3->setEnabled(1);ui->pushButton_4->setEnabled(1);}
}/**************** Ctrl + Z ****************/
void Widget::keyPressEvent(QKeyEvent *event)
{if(event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Z){qDebug() << "Ctrl + Z 按下";// 如果容器不為空if (!per_start_list.isEmpty()){// 則允許遍歷撤銷while(lines_attr.last().line.p1() != per_start_list.last()){qDebug() << "成功進入p1()";// 則刪除最后一個元素lines_attr.removeLast();}lines_attr.removeLast();per_start_list.removeLast();}update(); //手動更新,觸發繪圖}
}
效果
顏色的隨時調整
橡皮擦
撤銷上一步
撤銷完全