300 lines
13 KiB
C++
300 lines
13 KiB
C++
#include "screenshotwidget.h"
|
||
|
||
ScreenShotWidget::ScreenShotWidget(QWidget *parent) :
|
||
QWidget(parent)
|
||
{
|
||
//初始化截图激活标志
|
||
m_screenshot_active=false;
|
||
//设置窗口,无边框,顶部显示
|
||
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
|
||
setWindowModality(Qt::ApplicationModal);
|
||
//窗口背景为透明
|
||
setAttribute(Qt::WA_TranslucentBackground);
|
||
//设置窗口跟踪鼠标移动事件
|
||
setMouseTracking(true);
|
||
//设置保存、取消按钮以及长宽label并暂时隐藏
|
||
buttonSave=new QPushButton(this);
|
||
buttonSave->setParent(this);
|
||
buttonSave->setFixedSize(35,30);
|
||
buttonSave->setText("ok");
|
||
buttonSave->setStyleSheet("QPushButton {font-size:16pt; color:green; font-weight:800;}");
|
||
buttonSave->setVisible(false);
|
||
buttonCancel=new QPushButton(this);
|
||
buttonCancel->setParent(this);
|
||
buttonCancel->setFixedSize(35,30);
|
||
buttonCancel->setText("x");
|
||
buttonCancel->setStyleSheet("QPushButton {font-size:20pt; color:red;font-weight:100;}");
|
||
buttonCancel->setVisible(false);
|
||
lblHeightWidth=new QLabel(this);
|
||
lblHeightWidth->setParent(this);
|
||
lblHeightWidth->setFixedSize(100,10);
|
||
lblHeightWidth->setStyleSheet("QLabel {color:white;}");
|
||
lblHeightWidth->setVisible(false);
|
||
//设置放大镜
|
||
lblMagnifyGlass=new QLabel(this);
|
||
lblMagnifyGlass->setParent(this);
|
||
lblMagnifyGlass->setFixedSize(100,100);
|
||
lblMagnifyGlass->setVisible(true);
|
||
lblMagnifyGlass->setText("wo zai zhe");
|
||
//设置鼠标光标模式为十字
|
||
setCursor(Qt::CursorShape::CrossCursor);
|
||
//连接按钮的信号槽
|
||
connect(this->buttonSave,SIGNAL(clicked()),this,SLOT(on_buttonSave_Clicked()));
|
||
connect(this->buttonCancel,SIGNAL(clicked()),this,SLOT(on_buttonCancel_Clicked()));
|
||
}
|
||
|
||
void ScreenShotWidget::mousePressEvent(QMouseEvent *event)
|
||
{
|
||
if(event->button()==Qt::LeftButton)
|
||
{
|
||
QRect rect(m_startPos,m_endPos);
|
||
if((rect.contains(event->pos())||m_cursorMode!=0)&&m_startPos!=m_endPos){
|
||
m_oldPos=event->pos();
|
||
}
|
||
else if(m_startPos==m_endPos){
|
||
//记录鼠标点击的起始位置
|
||
m_startPos = event->pos();
|
||
//截图激活标志
|
||
m_screenshot_active=true;
|
||
}
|
||
}
|
||
else if(event->button()==Qt::RightButton)//重新截图
|
||
{
|
||
if(m_endPos.isNull())
|
||
on_buttonCancel_Clicked();
|
||
m_startPos=QPoint(0,0);
|
||
m_endPos=QPoint(0,0);
|
||
buttonSave->setVisible(false);
|
||
buttonCancel->setVisible(false);
|
||
lblHeightWidth->setVisible(false);
|
||
setCursor(Qt::CursorShape::CrossCursor);
|
||
update();
|
||
}
|
||
}
|
||
|
||
void ScreenShotWidget::mouseMoveEvent(QMouseEvent *event)
|
||
{
|
||
QRect rect(m_startPos,m_endPos);
|
||
QPoint point=getPointInWhichSqure(event->pos());
|
||
//截图后不点击鼠标时的光标更新
|
||
if(!m_screenshot_active && m_startPos!=m_endPos && !event->buttons()){
|
||
if(point==m_topLeft) {setCursor(Qt::CursorShape::SizeFDiagCursor);m_cursorMode=1;}
|
||
else if(point==m_topRight) {setCursor(Qt::CursorShape::SizeBDiagCursor);m_cursorMode=2;}
|
||
else if(point==m_bottomLeft) {setCursor(Qt::CursorShape::SizeBDiagCursor);m_cursorMode=3;}
|
||
else if(point==m_bottomRight) {setCursor(Qt::CursorShape::SizeFDiagCursor);m_cursorMode=4;}
|
||
else if(point==m_topCenter) {setCursor(Qt::CursorShape::SizeVerCursor);m_cursorMode=5;}
|
||
else if(point==m_bottomCenter) {setCursor(Qt::CursorShape::SizeVerCursor);m_cursorMode=6;}
|
||
else if(point==m_leftCenter) {setCursor(Qt::CursorShape::SizeHorCursor);m_cursorMode=7;}
|
||
else if(point==m_rightCenter) {setCursor(Qt::CursorShape::SizeHorCursor);m_cursorMode=8;}
|
||
else if(rect.contains(event->pos())) {setCursor(Qt::CursorShape::ClosedHandCursor);m_cursorMode=9;}
|
||
else {setCursor(Qt::CursorShape::ArrowCursor);m_cursorMode=0;}
|
||
}
|
||
//鼠标左键按下
|
||
if(event->buttons() & Qt::LeftButton)
|
||
{
|
||
//截图中位置更新
|
||
if(m_screenshot_active){
|
||
m_endPos = event->pos();
|
||
}
|
||
//拖动已截图区域
|
||
if(rect.contains(event->pos()) && !m_screenshot_active &&cursor().shape()==Qt::ClosedHandCursor){
|
||
m_distancePos=event->pos()-m_oldPos;
|
||
m_oldPos=event->pos();
|
||
m_startPos=m_startPos+m_distancePos;
|
||
m_endPos=m_endPos+m_distancePos;
|
||
//边界条件限制
|
||
if(m_startPos.x()<=0){m_startPos.rx()=0;m_endPos.rx()=m_endPos.x()-m_distancePos.x();}
|
||
if(m_startPos.y()<=0){m_startPos.ry()=0;m_endPos.ry()=m_endPos.y()-m_distancePos.y();}
|
||
if(m_endPos.x()>=this->width()){m_endPos.rx()=this->width();m_startPos.rx()=m_startPos.x()-m_distancePos.x();}
|
||
if(m_endPos.y()>=this->height()){m_endPos.ry()=this->height();m_startPos.ry()=m_startPos.y()-m_distancePos.y();}
|
||
}
|
||
else if(cursor().shape()==Qt::SizeFDiagCursor)
|
||
{
|
||
if(m_cursorMode==1){
|
||
m_distancePos=event->pos()-m_oldPos;
|
||
m_oldPos=event->pos();
|
||
m_startPos=m_startPos+m_distancePos;
|
||
}
|
||
if(m_cursorMode==4){
|
||
m_distancePos=event->pos()-m_oldPos;
|
||
m_oldPos=event->pos();
|
||
m_endPos=m_endPos+m_distancePos;
|
||
}
|
||
}
|
||
else if(cursor().shape()==Qt::SizeBDiagCursor)
|
||
{
|
||
if(m_cursorMode==2){
|
||
m_distancePos=event->pos()-m_oldPos;
|
||
m_oldPos=event->pos();
|
||
m_startPos.ry()=m_startPos.y()+m_distancePos.y();
|
||
m_endPos.rx()=m_endPos.x()+m_distancePos.x();
|
||
}
|
||
if(m_cursorMode==3){
|
||
m_distancePos=event->pos()-m_oldPos;
|
||
m_oldPos=event->pos();
|
||
m_startPos.rx()=m_startPos.x()+m_distancePos.x();
|
||
m_endPos.ry()=m_endPos.y()+m_distancePos.y();
|
||
}
|
||
}
|
||
else if(cursor().shape()==Qt::SizeHorCursor)
|
||
{
|
||
if(m_cursorMode==7){
|
||
m_distancePos=event->pos()-m_oldPos;
|
||
m_oldPos=event->pos();
|
||
m_startPos.rx()=m_startPos.x()+m_distancePos.x();
|
||
}
|
||
if(m_cursorMode==8){
|
||
m_distancePos=event->pos()-m_oldPos;
|
||
m_oldPos=event->pos();
|
||
m_endPos.rx()=m_endPos.x()+m_distancePos.x();
|
||
}
|
||
}
|
||
else if(cursor().shape()==Qt::SizeVerCursor)
|
||
{
|
||
if(m_cursorMode==5){
|
||
m_distancePos=event->pos()-m_oldPos;
|
||
m_oldPos=event->pos();
|
||
m_startPos.ry()=m_startPos.y()+m_distancePos.y();
|
||
}
|
||
if(m_cursorMode==6){
|
||
m_distancePos=event->pos()-m_oldPos;
|
||
m_oldPos=event->pos();
|
||
m_endPos.ry()=m_endPos.y()+m_distancePos.y();
|
||
}
|
||
}
|
||
update();
|
||
}
|
||
|
||
}
|
||
|
||
void ScreenShotWidget::mouseReleaseEvent(QMouseEvent *event)
|
||
{
|
||
Q_UNUSED(event);
|
||
if (m_screenshot_active) {
|
||
m_screenshot_active=false;
|
||
if (m_endPos != m_startPos) {
|
||
//弹出保存/取消按钮
|
||
buttonSave->setVisible(true);
|
||
buttonCancel->setVisible(true);
|
||
}
|
||
}
|
||
}
|
||
|
||
void ScreenShotWidget::paintEvent(QPaintEvent *event)
|
||
{
|
||
Q_UNUSED(event);
|
||
QPainter painter(this);
|
||
painter.fillRect(rect(),QColor(128,128,128,128));
|
||
QColor color(11,218,81);
|
||
QPen pen(color,1,Qt::SolidLine);
|
||
painter.setPen(pen);
|
||
//边界条件限制
|
||
if(m_startPos.x()>=m_endPos.x())m_endPos.rx()=m_startPos.x();
|
||
if(m_startPos.y()>=m_endPos.y())m_endPos.ry()=m_startPos.y();
|
||
//画矩形,并将内部置为透明
|
||
QRect rect(m_startPos, m_endPos);
|
||
painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||
painter.fillRect(rect,QColor(0,0,0,0));
|
||
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||
painter.drawRect(rect.normalized());
|
||
// 获取矩形的四个顶点和四条边的中点
|
||
m_topLeft=QPoint(rect.left(),rect.top());
|
||
m_topRight=QPoint(rect.right()+1,rect.top());
|
||
m_bottomLeft=QPoint(rect.left(),rect.bottom()+1);
|
||
m_bottomRight=QPoint(rect.right()+1,rect.bottom()+1);
|
||
m_topCenter=QPoint(rect.center().x(), rect.top());
|
||
m_bottomCenter=QPoint(rect.center().x(), rect.bottom()+1);
|
||
m_leftCenter=QPoint(rect.left(), rect.center().y());
|
||
m_rightCenter=QPoint(rect.right()+1, rect.center().y()+1);
|
||
|
||
// 定义一个小矩形的大小,用来画实心点
|
||
int pointSize = 5;
|
||
QRect pointRect(0, 0, pointSize, pointSize);
|
||
|
||
// 在每个点的位置画一个小矩形,作为实心点
|
||
pointRect.moveCenter(m_topLeft);
|
||
painter.fillRect(pointRect, color);
|
||
pointRect.moveCenter(m_topRight);
|
||
painter.fillRect(pointRect, color);
|
||
pointRect.moveCenter(m_bottomLeft);
|
||
painter.fillRect(pointRect, color);
|
||
pointRect.moveCenter(m_bottomRight);
|
||
painter.fillRect(pointRect, color);
|
||
pointRect.moveCenter(m_topCenter);
|
||
painter.fillRect(pointRect, color);
|
||
pointRect.moveCenter(m_bottomCenter);
|
||
painter.fillRect(pointRect, color);
|
||
pointRect.moveCenter(m_leftCenter);
|
||
painter.fillRect(pointRect, color);
|
||
pointRect.moveCenter(m_rightCenter);
|
||
painter.fillRect(pointRect, color);
|
||
//显示放大镜
|
||
if(cursor().shape()!=Qt::ClosedHandCursor)
|
||
{
|
||
QRect cursorRect(QCursor::pos().x()-25,QCursor::pos().y()-25,51,51);
|
||
QScreen *screen=QGuiApplication::primaryScreen();
|
||
QPixmap cursorPixmap=screen->grabWindow(QApplication::desktop()->winId(),cursorRect.x(),cursorRect.y(),cursorRect.width(),cursorRect.height());
|
||
cursorPixmap=cursorPixmap.scaled(cursorPixmap.width()*2,cursorPixmap.height()*2,Qt::KeepAspectRatio);
|
||
QPoint startPoint(QCursor::pos().x()+26,QCursor::pos().y()+26);
|
||
painter.drawPixmap(startPoint.x(),startPoint.y(),cursorPixmap.width(),cursorPixmap.height(),cursorPixmap);
|
||
painter.drawRect(startPoint.x(),startPoint.y(),cursorPixmap.width(),cursorPixmap.height());
|
||
QPen pen2(color,2,Qt::SolidLine);
|
||
painter.setPen(pen2);
|
||
painter.drawLine(startPoint.x(),startPoint.y()+cursorPixmap.height()/2+1,startPoint.x()+cursorPixmap.width(),startPoint.y()+cursorPixmap.height()/2+1);
|
||
painter.drawLine(startPoint.x()+cursorPixmap.width()/2+1,startPoint.y(),startPoint.x()+cursorPixmap.width()/2+1,startPoint.y()+cursorPixmap.height());
|
||
}
|
||
update();
|
||
//显示按钮与标签
|
||
if(this->height()<m_endPos.y()+30){
|
||
buttonSave->move(rect.x()+rect.width()-buttonSave->width()-10,rect.y()+rect.height()-30);
|
||
buttonCancel->move(rect.x()+rect.width()-buttonSave->width()-buttonCancel->width()-8,rect.y()+rect.height()-30);
|
||
}
|
||
else{
|
||
buttonSave->move(rect.x()+rect.width()-buttonSave->width()-10,rect.y()+rect.height());
|
||
buttonCancel->move(rect.x()+rect.width()-buttonSave->width()-buttonCancel->width()-8,rect.y()+rect.height());
|
||
}
|
||
lblHeightWidth->setVisible(true);
|
||
lblHeightWidth->move(rect.x(),rect.y()-12);
|
||
lblHeightWidth->setText(QString::number(rect.width())+"x"+QString::number(rect.height()));
|
||
}
|
||
|
||
void ScreenShotWidget::on_buttonSave_Clicked()
|
||
{
|
||
//清除笔刷,创建一个矩形区域
|
||
close();
|
||
QThread::msleep(30);
|
||
QRect rect = QRect(m_startPos, m_endPos);
|
||
emit(rect_selected(rect));
|
||
|
||
//获取存储路径
|
||
QDateTime currentDate=QDateTime::currentDateTime();
|
||
QString mCURDIr = QCoreApplication::applicationDirPath();
|
||
QString filePath=mCURDIr + "/screenshot/"+currentDate.toString("MMdd_hhmmss")+".bmp";
|
||
QDir dir;
|
||
if(!dir.exists(mCURDIr + "/screenshot")) dir.mkdir(mCURDIr + "/screenshot");
|
||
//获取矩形区域截图(减去笔刷),存储在pixmap中
|
||
QScreen *screen=QGuiApplication::primaryScreen();
|
||
QPixmap pixmap=screen->grabWindow(QApplication::desktop()->winId(),rect.x(),rect.y(),rect.width(),rect.height());
|
||
if (!pixmap.save(filePath)) QMessageBox::warning(this, tr("提示"), tr("保存图片失败"));
|
||
}
|
||
|
||
void ScreenShotWidget::on_buttonCancel_Clicked()
|
||
{
|
||
//关闭透明页面
|
||
close();
|
||
}
|
||
|
||
QPoint ScreenShotWidget::getPointInWhichSqure(QPoint point)
|
||
{
|
||
int distance=8;
|
||
if(abs(point.x()-m_topLeft.x())+abs(point.y()-m_topLeft.y())<distance) return m_topLeft;
|
||
else if(abs(point.x()-m_topRight.x())+abs(point.y()-m_topRight.y())<distance) return m_topRight;
|
||
else if(abs(point.x()-m_bottomLeft.x())+abs(point.y()-m_bottomLeft.y())<distance) return m_bottomLeft;
|
||
else if(abs(point.x()-m_bottomRight.x())+abs(point.y()-m_bottomRight.y())<distance) return m_bottomRight;
|
||
else if(abs(point.x()-m_topCenter.x())+abs(point.y()-m_topCenter.y())<distance) return m_topCenter;
|
||
else if(abs(point.x()-m_bottomCenter.x())+abs(point.y()-m_bottomCenter.y())<distance) return m_bottomCenter;
|
||
else if(abs(point.x()-m_leftCenter.x())+abs(point.y()-m_leftCenter.y())<distance) return m_leftCenter;
|
||
else if(abs(point.x()-m_rightCenter.x())+abs(point.y()-m_rightCenter.y())<distance) return m_rightCenter;
|
||
else return QPoint(-1,-1);
|
||
}
|