Last active
August 31, 2023 10:49
-
-
Save w4ngzhen/1ba20c81d8ba59d37b21a6e7e1363549 to your computer and use it in GitHub Desktop.
simple screen capture demo based Qt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <QApplication> | |
#include <QPainter> | |
#include <QWidget> | |
#include <QKeyEvent> | |
#include <QRect> | |
#include <QPoint> | |
#include <QImage> | |
#include <QCursor> | |
#include <QClipboard> | |
enum Status { | |
Explore = 0, | |
Capturing, | |
Captured | |
}; | |
class DemoWidget : public QWidget { | |
public: | |
explicit DemoWidget(QImage *img) { | |
setMouseTracking(true); | |
this->screenImg = img; | |
} | |
void paintEvent(QPaintEvent *event) override { | |
QPainter painter(this); | |
painter.drawImage(QRect(QPoint(0, 0), this->size()), | |
*this->screenImg); | |
if (status == Explore) { | |
return; | |
} | |
if (status == Capturing) { | |
painter.setPen(QPen(Qt::red)); | |
int w = abs(currX - startX); | |
int h = abs(currY - startY); | |
int left = startX < currX ? startX : currX; | |
int top = startY < currY ? startY : currY; | |
painter.drawRect(left, top, w, h); | |
return; | |
} | |
if (status == Captured) { | |
painter.setPen(QPen(Qt::blue)); | |
painter.drawRect(capturedRect); | |
return; | |
} | |
} | |
protected: | |
void mousePressEvent(QMouseEvent *event) override { | |
switch (status) { | |
case Explore: { | |
status = Capturing; // 进入Capturing | |
startX = event->pos().x(); | |
startY = event->pos().y(); | |
currX = startX; | |
currY = startY; | |
break; | |
} | |
default:break; // 其余状态都不关心 | |
} | |
this->update(); | |
} | |
void mouseReleaseEvent(QMouseEvent *event) override { | |
switch (status) { | |
case Capturing: { | |
// 进入Captured态 | |
status = Captured; | |
// 保存区域 | |
int w = abs(currX - startX); | |
int h = abs(currY - startY); | |
int left = startX < currX ? startX : currX; | |
int top = startY < currY ? startY : currY; | |
capturedRect = QRect(left, top, w, h); | |
break; | |
} | |
default: break; | |
} | |
this->update(); | |
} | |
void mouseMoveEvent(QMouseEvent *event) override { | |
switch (status) { | |
case Capturing: { | |
auto pos = event->pos(); | |
currX = pos.x(); | |
currY = pos.y(); | |
break; | |
} | |
default:break; | |
} | |
this->update(); | |
} | |
void keyPressEvent(QKeyEvent *event) override { | |
if (event->key() == Qt::Key_Return && status == Captured) { | |
// 1. 获取捕获的图像区域 | |
auto picRealSize = screenImg->size(); | |
auto winSize = this->size(); | |
int realRectX = capturedRect.x() * picRealSize.width() / winSize.width(); | |
int realRectY = capturedRect.y() * picRealSize.height() / winSize.height(); | |
int realRectW = | |
capturedRect.width() * picRealSize.width() / winSize.width(); | |
int realRectH = | |
capturedRect.height() * picRealSize.height() / winSize.height(); | |
QRect imgRect(realRectX, realRectY, realRectW, realRectH); | |
// 2. 从保存的屏幕图像中获取指定区域的图像数据 | |
auto copiedImg = this->screenImg->copy(imgRect); | |
// 3. 将图像数据写入到操作系统粘贴板 | |
QClipboard *clipboard = QGuiApplication::clipboard(); | |
clipboard->setImage(copiedImg); | |
// 4. 回到Explore | |
status = Explore; | |
return; | |
} | |
if (event->key() == Qt::Key_Escape) { | |
status = Explore; | |
} | |
this->update(); | |
} | |
private: | |
int startX = 0, startY = 0; | |
int currX = 0, currY = 0; | |
QRect capturedRect; | |
Status status = Explore; | |
QImage *screenImg; | |
}; | |
int main(int argc, char *argv[]) { | |
QApplication a(argc, argv); | |
QScreen *screen = QApplication::screenAt(QCursor().pos()); | |
QImage screenImg = screen->grabWindow(0).toImage(); | |
DemoWidget w(&screenImg); | |
w.resize(400, 300); | |
w.show(); | |
return QApplication::exec(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment