一、简述
在 Qt 之 简单截图功能(三)实现可拖拽选中区域 中 实现了截图的基本功能,今天讲述的是在选取截图区域时,实时显示当前的截图信息,具体仿照了QQ的截图功能。
先看一下效果图:
在放大图窗口要超出下方屏幕时更改显示位置。
二、代码之路
这里主要是在paintEvent事件中绘制截图信息 , 关于截图功能的代码可以查看 Qt 之 简单截图功能(三)实现可拖拽选中区域。
仿照QQ截图功能,在截图时 实时捕获当前截取区域的大小,同时显示鼠标位置区域的放大图,这里为什么QQ要放大鼠标拖动点区域,也是因为能够更精确地截取到我们实际想要的部分。
在放大图片下方显示了窗口大小信息,而左上角也显示截取区域大小,这个感觉上可能有点多余。实际则不是,因为我们在截图时一般留意的是截图区域的右下方,也就是鼠标当前的位置,所以这里显示了当前截取的大小,更利于我们查看。我们也可以在放大图下方看到当前鼠标位置图片的RGB值。这一个小功能非常好,我们在日常要取某个颜色时,就能直接利用此功能。
比如我之前模仿QQ登录界面,一些背景色的RGB取值都是利用QQ的截图功能获取到,所以功能虽小,但确是十分好用。
// 矩形选中区边框宽度;
#define SELECT_RECT_BORDER_WIDTH 1
// 选中矩形8个拖拽点小矩形的宽高;
#define STRETCH_RECT_WIDTH 6
#define STRETCH_RECT_HEIGHT 6
// 选中矩形信息矩形的宽高;
#define SELECT_RECT_INFO_WIDTH 75
#define SELECT_RECT_INFO_HEIGHT 20
// 选区矩形的右下顶点放大图的宽高;
#define END_POINT_RECT_WIDTH 122
#define END_POINT_RECT_HEIGHT 122
#define END_POINT_IMAGE_HEIGHT 90
// 绘制选中矩形信息;
void CaptureScreen::drawSelectRectInfo()
{
int posX, posY;
QPoint topLeftPoint = m_currentSelectRect.topLeft();
posX = topLeftPoint.x() + SELECT_RECT_BORDER_WIDTH;
if (topLeftPoint.y() > SELECT_RECT_INFO_HEIGHT)
{
posY = topLeftPoint.y() - SELECT_RECT_INFO_HEIGHT - SELECT_RECT_BORDER_WIDTH;
}
else
{
posY = topLeftPoint.y() + SELECT_RECT_BORDER_WIDTH;
}
topLeftPoint = QPoint(posX, posY);
QColor backColor = QColor(0, 0, 0, 160);
m_painter.fillRect(QRect(topLeftPoint, QSize(SELECT_RECT_INFO_WIDTH, SELECT_RECT_INFO_HEIGHT)), backColor);
// 当前选中矩形的宽高信息;
QString selectRectSizeInfo = QString("%1 * %2").arg(m_currentSelectRect.width()).arg(m_currentSelectRect.height());
int fontWidth = this->fontMetrics().width(selectRectSizeInfo);
m_painter.setPen(QPen(Qt::white));
m_painter.drawText(QPoint(topLeftPoint.x() + (SELECT_RECT_INFO_WIDTH - fontWidth) / 2, topLeftPoint.y() + 14), selectRectSizeInfo);
}
// 绘制鼠标拖拽时选区矩形的右下顶点的放大图;
void CaptureScreen::drawEndPointImage()
{
int posX, posY;
QPoint topLeftPoint = QCursor::pos();
// 5、25 分别为鼠标所在点距离放大图的X轴、Y轴距离;
//当放大图片区域超出右边屏幕时;
if (topLeftPoint.x() + END_POINT_RECT_WIDTH + 5 > m_screenwidth)
{
// 这里暂时未考虑到双屏幕(多屏幕);
if (topLeftPoint.x() > m_screenwidth)
{
posX = m_screenwidth - END_POINT_RECT_WIDTH - 5;
}
else
{
posX = topLeftPoint.x() - END_POINT_RECT_WIDTH - 5;
}
}
else
{
posX = topLeftPoint.x() + 5;
}
// 当放大图片区域超出屏幕下方时;
if (topLeftPoint.y() + END_POINT_RECT_HEIGHT + 25 > m_screenheight)
{
posY = topLeftPoint.y() - END_POINT_RECT_HEIGHT - 25;
}
// 当鼠标未屏幕下方,正常显示时;
else
{
posY = topLeftPoint.y() + 25;
}
topLeftPoint = QPoint(posX, posY);
// 绘制放大图;
QPixmap endPointImage = m_loadPixmap.copy(QRect(QCursor::pos().x() - 15, QCursor::pos().y() - 11, 30, 22)).scaled(END_POINT_RECT_WIDTH, END_POINT_IMAGE_HEIGHT);
m_painter.drawPixmap(topLeftPoint, endPointImage);
// 绘制十字坐标;
m_painter.setPen(QPen(QColor(0, 180, 255 , 180), 4));
// 竖线;
m_painter.drawLine(QPoint(topLeftPoint.x() + END_POINT_RECT_WIDTH / 2, topLeftPoint.y() + 2), QPoint(topLeftPoint.x() + END_POINT_RECT_WIDTH / 2, topLeftPoint.y() + END_POINT_IMAGE_HEIGHT - 2));
// 横线;
m_painter.drawLine(QPoint(topLeftPoint.x() + 2 , topLeftPoint.y() + END_POINT_IMAGE_HEIGHT / 2), QPoint(topLeftPoint.x() + END_POINT_RECT_WIDTH - 2 , topLeftPoint.y() + END_POINT_IMAGE_HEIGHT / 2));
m_painter.setPen(QPen(Qt::white, 3));
m_painter.drawRect(QRect(QPoint(topLeftPoint.x() + 1 , topLeftPoint.y() + 1), QSize(END_POINT_RECT_WIDTH - 2, END_POINT_IMAGE_HEIGHT - 2)));
m_painter.setPen(QPen(Qt::black, 1));
m_painter.drawRect(QRect(topLeftPoint, QSize(END_POINT_RECT_WIDTH, END_POINT_IMAGE_HEIGHT)));
// 绘制放大图信息;
topLeftPoint = QPoint(topLeftPoint.x(), topLeftPoint.y() + END_POINT_IMAGE_HEIGHT);
QColor backColor = QColor(0, 0, 0, 160);
m_painter.fillRect(QRect(topLeftPoint, QSize(END_POINT_RECT_WIDTH, END_POINT_RECT_HEIGHT - END_POINT_IMAGE_HEIGHT)), backColor);
// 当前选中矩形的宽高信息;
QString selectRectSizeInfo = QString("%1 * %2").arg(m_currentSelectRect.width()).arg(m_currentSelectRect.height());
QImage image = m_loadPixmap.toImage();
QColor endPointColor = image.pixel(QCursor::pos());
QString selectPointRGBInfo = QString("RGB:(%1,%2,%3)").arg(endPointColor.red()).arg(endPointColor.green()).arg(endPointColor.blue());
m_painter.setPen(Qt::white);
m_painter.drawText(QPoint(topLeftPoint.x() + 6, topLeftPoint.y() + 14), selectRectSizeInfo);
m_painter.drawText(QPoint(topLeftPoint.x() + 6, topLeftPoint.y() + 27), selectPointRGBInfo);
}
尾
以上通过两个方法完成了在截图时在屏幕上绘制截图信息,这两个功能虽小,但是在截图的使用过程中却起到了很大的作用。同时我们也不仅仅可以用来截图,比如上方我提到的在模仿QQ界面时,获取某一种颜色的RGB值,也可以获取某个窗口或者窗口控件、屏幕上图片、文字等具体大小。
—— 更新于2017年1月23日