-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathscreencapture.cpp
More file actions
200 lines (166 loc) · 6.46 KB
/
screencapture.cpp
File metadata and controls
200 lines (166 loc) · 6.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#include "screencapture.h"
#include <QApplication>
#include <QScreen>
#include <QKeyEvent>
#include <QDateTime>
ScreenCapture::ScreenCapture(QWidget *parent) : QWidget(parent), isCapturing(false), isCloseButtonHovered(false)
{
// 设置窗口属性 - 确保完全覆盖屏幕且在最顶层
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Tool | Qt::X11BypassWindowManagerHint);
setAttribute(Qt::WA_TranslucentBackground);
setAttribute(Qt::WA_NoSystemBackground);
setMouseTracking(true);
// 获取全屏截图 - 冻结屏幕
QScreen *screen = QApplication::primaryScreen();
qreal screenScale = screen->devicePixelRatio();
// 获取全屏截图并设置正确的设备像素比例
fullScreen = screen->grabWindow(0);
fullScreen.setDevicePixelRatio(screenScale); // 显式告诉 QPixmap 它的比例
// 获取屏幕几何信息并设置窗口大小
QRect screenGeometry = screen->geometry();
resize(screenGeometry.size());
move(screenGeometry.topLeft());
// 初始化关闭按钮区域
closeButtonRect = QRect(width() - 50, 10, 40, 40);
// 显示窗口 - 全屏蒙层
showFullScreen();
raise();
activateWindow();
qDebug() << "屏幕几何信息:" << screenGeometry;
qDebug() << "屏幕缩放比例:" << screenScale;
qDebug() << "截图尺寸:" << fullScreen.size();
qDebug() << "截图设备像素比例:" << fullScreen.devicePixelRatio();
qDebug() << "窗口尺寸:" << size();
qDebug() << "窗口位置:" << pos();
}
ScreenCapture::~ScreenCapture()
{
}
void ScreenCapture::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
// 检查是否点击了关闭按钮
if (closeButtonRect.contains(event->pos())) {
emit captureCanceled();
close();
return;
}
startPoint = event->pos();
captureRect.setTopLeft(startPoint);
isCapturing = true;
}
}
void ScreenCapture::mouseMoveEvent(QMouseEvent *event)
{
if (isCapturing) {
captureRect.setBottomRight(event->pos());
update();
}
// 检测关闭按钮的悬停状态
bool wasHovered = isCloseButtonHovered;
isCloseButtonHovered = closeButtonRect.contains(event->pos());
if (wasHovered != isCloseButtonHovered) {
update(closeButtonRect);
}
}
void ScreenCapture::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton && isCapturing) {
isCapturing = false;
// 确保矩形有效
if (captureRect.width() > 10 && captureRect.height() > 10) {
// 调整矩形为正方向
QRect normalizedRect = captureRect.normalized();
// 确保矩形在屏幕范围内
normalizedRect = normalizedRect.intersected(rect());
// 核心修正:利用逻辑坐标直接裁切
// 如果 fullScreen 已经设置了正确的 DevicePixelRatio,
// 我们可以通过这种方式获取"物理像素级"的矩形:
qreal dpr = fullScreen.devicePixelRatio();
QRect realRect(
normalizedRect.x() * dpr,
normalizedRect.y() * dpr,
normalizedRect.width() * dpr,
normalizedRect.height() * dpr
);
// 添加调试信息
qDebug() << "原始捕获矩形:" << captureRect;
qDebug() << "规范化后矩形:" << normalizedRect;
qDebug() << "物理像素矩形:" << realRect;
qDebug() << "窗口矩形:" << rect();
qDebug() << "截图尺寸:" << fullScreen.size();
qDebug() << "截图设备像素比例:" << dpr;
// 截取选定区域 - 从全屏截图中复制对应区域
// 确保矩形在截图范围内
QRect screenshotRect(0, 0, fullScreen.width() * dpr, fullScreen.height() * dpr);
realRect = realRect.intersected(screenshotRect);
QPixmap screenshot = fullScreen.copy(realRect);
// 发送完成信号
emit captureCompleted(screenshot);
}
// 关闭窗口
close();
}
}
void ScreenCapture::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// 绘制全屏截图 - 作为底层图像
painter.drawPixmap(0, 0, fullScreen);
// 绘制半透明蒙层 - 覆盖整个屏幕
painter.setBrush(QColor(0, 0, 0, 100));
painter.drawRect(rect());
// 绘制右上角关闭按钮
painter.setRenderHint(QPainter::Antialiasing);
// 按钮背景
if (isCloseButtonHovered) {
painter.setBrush(QColor(255, 100, 100));
} else {
painter.setBrush(QColor(255, 255, 255, 200));
}
painter.setPen(QColor(200, 200, 200));
painter.drawRoundedRect(closeButtonRect, 20, 20);
// 按钮文字 ×
painter.setPen(QColor(51, 51, 51));
QFont font = painter.font();
font.setPointSize(18);
font.setBold(true);
painter.setFont(font);
painter.drawText(closeButtonRect, Qt::AlignCenter, "×");
// 绘制说明标签
QRect labelRect(width() - 200, 60, 180, 30);
painter.setBrush(QColor(0, 0, 0, 150));
painter.setPen(Qt::NoPen);
painter.drawRoundedRect(labelRect, 4, 4);
painter.setPen(Qt::white);
font.setPointSize(12);
font.setBold(false);
painter.setFont(font);
painter.drawText(labelRect, Qt::AlignCenter, "按ESC或点击×取消");
// 绘制选中区域
if (isCapturing) {
QRect rect = captureRect.normalized();
// 绘制选中区域的边框
painter.setPen(QPen(QColor(90, 138, 90), 2));
painter.setBrush(QBrush(QColor(90, 138, 90, 50)));
painter.drawRect(rect);
// 绘制选中区域的文字提示
painter.setPen(Qt::white);
painter.drawText(rect.topLeft() - QPoint(0, 20), "拖动鼠标选择截图区域");
} else {
// 绘制提示文字
painter.setPen(Qt::white);
painter.drawText(rect(), Qt::AlignCenter, "按鼠标左键拖动选择截图区域,按ESC或点击×取消");
}
}
void ScreenCapture::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Escape) {
// 发送取消信号
emit captureCanceled();
// 关闭窗口
close();
}
}