文章目录
- 1 效果图
- 2 思想
- 3 核心代码
1 效果图
从鼠标左键点击QLabel中的图片开始,然后到移动鼠标的过程中不断绘制矩形框,直到释放鼠标左键,形成一个完整的矩形框,最后图片按照矩形框大小被裁剪。
2 思想
- 1 使用事件过滤器,为QLabel安装事件过滤器,
- 2 重写事件过滤器,写鼠标左击、移动、释放事件
- 2.1 在事件中在鼠标左击QLabel时,获得相对于QLabel的起始坐标(x1,y1),为了能更方便剪裁,使得QLabel大小和图片一样大
- 2.2 在鼠标拖动的过程中,不断获得末端坐标(x2,y2),使用QPainter绘制的矩形为(x2-x1,y2-y1)
- 2.3 在鼠标释放时,使用QIamge.copy(x,y,width,height)剪裁图片
难点:一般都是在widget或者dialog上绘制图形,但是在控件上绘制图形需要一点小技巧。
3 核心代码
在类中写成员函数:
bool eventFilter(QObject *obj, QEvent *event);//事件过滤器
在构造函数中写安装事件过滤器:
//安装事件过滤器
ui->imageLabel->installEventFilter(this);
写过滤事件
bool Widget::eventFilter(QObject *obj, QEvent *event)
{
if(obj == ui->imageLabel){
if(event->type() == QEvent::MouseButtonPress){
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if(mouseEvent->button() == Qt::LeftButton){
isModify = true;
// QPoint pos;
// pos.setX(x+88);
// pos.setY(y+85);
// QCursor::setPos(pos);
QPoint pos = QCursor::pos();//获得相对于屏幕的坐标
QPoint sPoint1 = mouseEvent->globalPos();//获得相对于屏幕的坐标
QPoint pos2= ui->imageLabel->mapFromGlobal(pos);//获得相对于控件的坐标
//qDebug()<<"移动后:"<<"x:"<<pos2.x()<<"y:"<<pos2.y();
x1 = pos2.x();
y1 = pos2.y();
return true;
}else{
return false;
}
}else if(event->type() == QEvent::MouseMove){
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if(mouseEvent->buttons() == Qt::LeftButton){
QPoint pos = QCursor::pos();//获得相对于屏幕的坐标
//QPoint sPoint1 = mouseEvent->globalPos();//获得相对于屏幕的坐标
//sPoint1
QPoint pos2 = ui->imageLabel->mapFromGlobal(pos);//获得相对于控件的坐标
x2 = pos2.x();
y2 = pos2.y();
QPainter painter;
QImage tempImg = tempTestImg;
painter.begin(&tempImg);
painter.setPen(QPen(Qt::red, 2, Qt::DashDotLine, Qt::RoundCap));
painter.drawRect(x1, y1, x2 - x1, y2 - y1);
painter.end();
ui->imageLabel->setPixmap(QPixmap::fromImage(tempImg));
}else{
return false;
}
}else if(event->type() == QEvent::MouseButtonRelease){
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if(mouseEvent->button() == Qt::LeftButton){
QPoint pos = QCursor::pos();//获得相对于屏幕的坐标
//QPoint sPoint1 = mouseEvent->globalPos();//获得相对于屏幕的坐标
QPoint pos2= ui->imageLabel->mapFromGlobal(pos);//获得相对于控件的坐标
x2 = pos2.x();
y2 = pos2.y();
QPainter painter;
QImage tempImg = tempTestImg;
painter.begin(&tempImg);
//颜色、线宽、画笔风格、画笔端点风格、画笔连接风格
painter.setPen(QPen(Qt::red, 2, Qt::DashDotLine, Qt::RoundCap, Qt::RoundJoin));
painter.drawRect(x1, y1, x2 - x1, y2 - y1);
painter.end();
ui->imageLabel->setPixmap(QPixmap::fromImage(tempImg));
qDebug()<<"剪裁后x1:"<<x1;
qDebug()<<"剪裁后y1:"<<y1;
qDebug()<<"剪裁后x2:"<<x2;
qDebug()<<"剪裁后y2:"<<y2;
//本地裁剪
QImage testImg = tempTestImg.copy(x1, y1, x2 - x1, y2 - y1);
QPixmap resImage = QPixmap::fromImage(testImg);
// resImage.scaled(ui->imageLabel->size(), Qt::IgnoreAspectRatio);
ui->imageLabel->setScaledContents(true);
QSize size;
size.setWidth(testImg.width());
size.setHeight(testImg.height());
ui->imageLabel->resize(size);
ui->imageLabel->setPixmap(resImage);
}else{
return false;
}
}else{
return false;
}
}else {
return QWidget::eventFilter(obj, event);
}
}
把QLabel设置的和图片一样大小
QImage imageData;
imageData.load("1.png");
imageData = imageData.scaled(imageData.width()*multiple, imageData.height()*multiple, Qt::KeepAspectRatio, Qt::SmoothTransformation);
QPixmap resImage = QPixmap::fromImage(imageData);
// resImage.scaled(resWidth*6, resHeight*6, Qt::KeepAspectRatio, Qt::SmoothTransformation);
//resImage.scaled(ui->imageLabel->size(), Qt::IgnoreAspectRatio);
ui->imageLabel->setScaledContents(true);
QSize size;
size.setWidth(resImage.width());
size.setHeight(resImage.height());
ui->imageLabel->resize(size);
// ui->imageLabel->setGeometry(40, 60, resImage.width()*6, resImage.height()*6);
ui->imageLabel->setPixmap(resImage);
qDebug()<<"imageLabel:width:"<<ui->imageLabel->width();
qDebug()<<"imageLabel:height:"<<ui->imageLabel->height();
qDebug()<<"imageLabel:x:"<<ui->imageLabel->x();
qDebug()<<"imageLabel:y:"<<ui->imageLabel->y();
tempTestImg = imageData;