Skip to content

Instantly share code, notes, and snippets.

@w4ngzhen
Last active August 31, 2023 10:49
Show Gist options
  • Save w4ngzhen/1ba20c81d8ba59d37b21a6e7e1363549 to your computer and use it in GitHub Desktop.
Save w4ngzhen/1ba20c81d8ba59d37b21a6e7e1363549 to your computer and use it in GitHub Desktop.
simple screen capture demo based Qt
#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