php网站开发指导教材 文献,公司网站上传图片,html5创意网站,app网站开发长沙上一篇QT截图程序#xff0c;可多屏幕截图只是实现了最基本的截图功能#xff0c;虽然能用但是缺点也有#xff0c;没办法更改选中的区域#xff0c;这在实际使用时不太方便。这篇增加了这个功能。先看看效果。
实现代码为#xff1a;
头文件
#ifndef MASKWIDGET_H
#de…上一篇QT截图程序可多屏幕截图只是实现了最基本的截图功能虽然能用但是缺点也有没办法更改选中的区域这在实际使用时不太方便。这篇增加了这个功能。先看看效果。
实现代码为
头文件
#ifndef MASKWIDGET_H
#define MASKWIDGET_H#include QWidget
#include mainwindow.h
namespace Ui {
class MaskWidget;
}
enum SnapState{NoSnap,Snapped,PreLeftDrag,LeftDrag,PreRightDrag,RightDrag,PreTopDrag,TopDrag,PreBottomDrag,BottomDrag
};class MaskWidget : public QWidget
{Q_OBJECTpublic:explicit MaskWidget(QWidget *parent nullptr);~MaskWidget();
protected:void mousePressEvent(QMouseEvent *event)override;void mouseReleaseEvent(QMouseEvent *event)override;void mouseMoveEvent(QMouseEvent *event)override;void paintEvent(QPaintEvent *event)override;void keyPressEvent(QKeyEvent *event) override;void showEvent(QShowEvent *event) override;private slots:void ResetSnap();private:QPoint m_pressPos;QPoint m_newPos;QRect m_maskRect{0, 0, 0, 0};QPixmap m_image;bool isPressed{false};MainWindow m;SnapState snapstate{NoSnap};
private:Ui::MaskWidget *ui;};#endif // MASKWIDGET_H源文件
#include maskwidget.h
#include ui_maskwidget.h
#include QMouseEvent
#include QRegion
#include QScreen
#include QPainter
#include QGuiApplication
#include QPixmap
#include QDebug
#include QtMath
#include QCursorconst int MINSIZE 10;MaskWidget::MaskWidget(QWidget *parent) :QWidget(parent),ui(new Ui::MaskWidget)
{ui-setupUi(this);setMouseTracking(true);setWindowFlags(Qt::FramelessWindowHint);setWindowOpacity(0.8);QListQScreen* screens QGuiApplication::screens();int width 0;int height 0;for (QScreen *screen : screens){width screen-geometry().width();if (height screen-geometry().height()){height screen-geometry().height();}qDebug()screen-geometry();}this-setFixedSize(width, height);m.hide();connect(m, SIGNAL(resetSnap()), this, SLOT(ResetSnap()));
}MaskWidget::~MaskWidget()
{delete ui;
}void MaskWidget::mousePressEvent(QMouseEvent *event)
{if (event-button() Qt::LeftButton){if (m_maskRect.width() 0 m_maskRect.width() 0){m_pressPos event-pos();this-setCursor(Qt::CrossCursor);isPressed true;update();}if (snapstate PreLeftDrag){snapstate LeftDrag;}else if (snapstate PreRightDrag){snapstate RightDrag;}else if (snapstate PreTopDrag){snapstate TopDrag;}else if (snapstate PreBottomDrag){snapstate BottomDrag;}}if (event-button() Qt::RightButton){if (m_maskRect.width() 0){isPressed false;QRegion all(0, 0, width(), height());QRegion sub(m_maskRect);setMask(all.subtracted(sub));QPixmap combined(this-width(), this-height());combined.fill(Qt::transparent);QPainter painter(combined);QListQScreen* screens QGuiApplication::screens();for (QScreen *screen : screens){m_image screen-grabWindow(0);painter.drawPixmap(screen-geometry().x(), 0, screen-geometry().width(), screen-geometry().height(), m_image);}// auto gpos mapToGlobal(event-pos());
// auto gposStart mapToGlobal(m_pressPos);
// qDebug()gposgposStart;//m_image combined.copy(qMin(gpos.x(), gposStart.x()), qMin(gpos.y(), gposStart.y()),// qFabs(gpos.x() - gposStart.x()), qFabs(gpos.y() - gposStart.y()));m_image combined.copy(m_maskRect);this-hide();m.SetImage(m_image);update();m.show();}}QWidget::mousePressEvent(event);
}void MaskWidget::mouseReleaseEvent(QMouseEvent *event)
{qDebug()__func__ snapstate;if (isPressed){isPressed false;snapstate Snapped;this-setCursor(Qt::ArrowCursor);}switch(snapstate){case LeftDrag:{snapstate Snapped;this-setCursor(Qt::ArrowCursor);}break;case RightDrag:{snapstate Snapped;this-setCursor(Qt::ArrowCursor);}break;case TopDrag:{snapstate Snapped;this-setCursor(Qt::ArrowCursor);}break;case BottomDrag:{snapstate Snapped;this-setCursor(Qt::ArrowCursor);}break;default:break;}return QWidget::mouseReleaseEvent(event);
}void MaskWidget::mouseMoveEvent(QMouseEvent* event)
{if (isPressed){m_newPos event-pos();QRegion all(0, 0, width(), height());m_maskRect QRect(qMin(m_pressPos.x(), m_newPos.x()),qMin(m_pressPos.y(), m_newPos.y()),qAbs(m_newPos.x() - m_pressPos.x()),qAbs(m_newPos.y() - m_pressPos.y()));QRegion sub(m_maskRect);setMask(all.subtracted(sub));update();}else{switch(snapstate){case Snapped:{if (m_maskRect.bottom() event-pos().y() m_maskRect.top() event-pos().y()){if (qFabs(m_maskRect.left() - event-pos().x()) 5){this-setCursor(Qt::SizeHorCursor);this-snapstate PreLeftDrag;}else if (qFabs(m_maskRect.right() - event-pos().x()) 5){this-setCursor(Qt::SizeHorCursor);this-snapstate PreRightDrag;}}else if (m_maskRect.left() event-pos().x() m_maskRect.right() event-pos().y()){if (qFabs(m_maskRect.top() - event-pos().y()) 5){this-setCursor(Qt::SizeVerCursor);this-snapstate PreTopDrag;}else if (qFabs(m_maskRect.bottom() - event-pos().y()) 5){this-setCursor(Qt::SizeVerCursor);this-snapstate PreBottomDrag;}}}break;case LeftDrag:{if (event-pos().x() MINSIZE m_maskRect.right()){m_maskRect.setLeft(m_maskRect.right() - MINSIZE);}else{m_maskRect.setLeft(event-pos().x() 2);}QRegion sub(m_maskRect);QRegion all(0, 0, width(), height());setMask(all.subtracted(sub));qDebug()m_maskRect;update();}break;case PreLeftDrag:{if (qFabs(m_maskRect.left() - event-pos().x()) 5 || event-pos().y() m_maskRect.bottom() || event-pos().y() m_maskRect.top()){this-setCursor(Qt::ArrowCursor);this-snapstate Snapped;}}break;case PreRightDrag:{if (qFabs(event-pos().x() - m_maskRect.right()) 5 || event-pos().y() m_maskRect.bottom() || event-pos().y() m_maskRect.top()){this-setCursor(Qt::ArrowCursor);this-snapstate Snapped;}}break;case RightDrag:{if (event-pos().x() - MINSIZE m_maskRect.left()){m_maskRect.setRight(m_maskRect.left() MINSIZE);}else{m_maskRect.setRight(event-pos().x() - 2);}QRegion sub(m_maskRect);QRegion all(0, 0, width(), height());setMask(all.subtracted(sub));qDebug()m_maskRect;update();}break;case PreTopDrag:{if (qFabs(event-pos().y() - m_maskRect.top()) 5 || event-pos().x() m_maskRect.left() || event-pos().x() m_maskRect.right()){this-setCursor(Qt::ArrowCursor);this-snapstate Snapped;}}break;case TopDrag:{if (event-pos().y() MINSIZE m_maskRect.bottom()){m_maskRect.setTop(m_maskRect.bottom() - MINSIZE);}else{m_maskRect.setTop(event-pos().y() 2);}QRegion sub(m_maskRect);QRegion all(0, 0, width(), height());setMask(all.subtracted(sub));update();}break;case PreBottomDrag:{if (qFabs(event-pos().y() - m_maskRect.bottom()) 5 || event-pos().x() m_maskRect.left() || event-pos().x() m_maskRect.right()){this-setCursor(Qt::ArrowCursor);this-snapstate Snapped;}}break;case BottomDrag:{if (event-pos().y() - MINSIZE m_maskRect.top()){m_maskRect.setBottom(m_maskRect.top() MINSIZE);}else{m_maskRect.setBottom(event-pos().y() - 2);}QRegion sub(m_maskRect);QRegion all(0, 0, width(), height());setMask(all.subtracted(sub));update();}break;default:break;}}return QWidget::mouseMoveEvent(event);
}void MaskWidget::paintEvent(QPaintEvent *)
{QPainter painter(this);painter.setPen(Qt::red);painter.drawRect(m_maskRect.x()-1, m_maskRect.y()-1, m_maskRect.width()1, m_maskRect.height() 1);}void MaskWidget::keyPressEvent(QKeyEvent *event)
{if (event-key() Qt::Key_Escape){close();}else if (event-key() Qt::Key_Enter){if (isPressed){isPressed false;snapstate Snapped;this-setCursor(Qt::ArrowCursor);}}QWidget::keyPressEvent(event);
}void MaskWidget::showEvent(QShowEvent *event)
{QWidget::showEvent(event);
}void MaskWidget::ResetSnap()
{QRegion all(0, 0, width(), height());setMask(all);m_maskRect.setRect(0,0,0,0);snapstate NoSnap;this-show();
}思路
第一要保留住选中的框选中后停留下来不自动跳转。实现方式为在mouseRelease函数里面不再进行隐藏和跳转跳转改称点击鼠标右键。 第二当鼠标移动到边框附近时鼠标的形状要进行变化表示可以拖动了。左右边对应的是双向横箭头上下边对应的是双向竖箭头。这里取值距离5作为触发区域当距离小于5时可进行拖动。类似途中的红色区域。 第三为了配合形状变化用一个枚举来表示不同的状态。
enum SnapState{NoSnap,Snapped,PreLeftDrag,LeftDrag,PreRightDrag,RightDrag,PreTopDrag,TopDrag,PreBottomDrag,BottomDrag
};
NoSnap表示初始状态没有开始截图的时候。
Snapped表示已经截图了此时会显示一个矩形方框。
PreLeftDrag表示进入左侧边框可拖动状态此时鼠标形状变化成左右箭头。 PreLeftDrag----按下鼠标左键---LeftDrag可移动鼠标来拖动边框 PreLeftDrag----鼠标距离左边框的距离大于5---Snapped鼠标状态恢复正常
LeftDrag表示进入可拖动状态可拖动鼠标更改左边框位置。此时松开鼠标则回到PreLeftDrag状态
其他几个状态类似。 根据鼠标的位置和动作变化不同的状态。这里由于逻辑简单没有使用状态机。
为了有更好的显示效果这里限制了拖动区域不会出现一条边覆盖另一条的情况可在动图里看出来。
这样修改后截图工具好用了很多。