目前百度能百度到的,都是让大家调用以下方法获取屏幕
QGuiApplication::primaryScreen();
但这个函数只能获取主屏幕,对多个显示器的截屏就完全不好使了。
所以用以下方法获取所有显示器,并判断当前鼠标、界面位于哪个显示器,即可实现多个屏幕的截图。
int curMonitor = deskTop->screenNumber ( this );
this->baseScreen = screens.at(curMonitor);
截图主要事件为鼠标按下,鼠标移动,鼠标抬起。需要一个全局的点来标记鼠标最开始按下时的点。
以下为三个事件的处理:
void QtScreenShot::mousePressEvent(QMouseEvent* e)
{
this->startPoint = e->pos();
this->startGlobalPoint = e->globalPos();
}
void QtScreenShot::mouseMoveEvent(QMouseEvent* e)
{
QPoint curPoint;
curPoint = e->pos();
if (hasArea)
{
qDebug() << "return";
return;
}
int posX = startPoint.x();
int posY = startPoint.y();
int posWid = curPoint.x() - startPoint.x();
int posHig = curPoint.y() - startPoint.y();
this->editArea->setGeometry(posX, posY, posWid, posHig);
QImage ima = this->getSelectImage(posX, posY, posWid, posHig);
this->editArea->setBgImage(ima);
this->editArea->show();
}
void QtScreenShot::mouseReleaseEvent(QMouseEvent* e)
{
if (e->button() == Qt::RightButton)
{
closeAll();
this->accept();
return;
}
if (hasArea)
{
qDebug() << "return";
return;
}
QPoint curPoint;
curPoint = e->pos();
int posX = startPoint.x();
int posY = startPoint.y();
int posWid = curPoint.x() - startPoint.x();
int posHig = curPoint.y() - startPoint.y();
QPoint glcurPoint;
glcurPoint = e->globalPos();
this->globalSelectArea.setRect(startGlobalPoint.x(), startGlobalPoint.y(), glcurPoint.x() - startGlobalPoint.x(), glcurPoint.y() - startGlobalPoint.y());
this->editArea->setGeometry(posX, posY, posWid, posHig);
QImage ima = this->getSelectImage(posX, posY, posWid, posHig);
this->editArea->setBgImage(ima);
this->editArea->show();
this->toolBar->setPos(curPoint.x(), curPoint.y());
this->toolBar->show();
this->hasArea = true;
}
以下为我写的一个demo。测试界面位于哪个屏幕,就可以在哪个屏幕截图,同时还提供操作撤销功能。
如果需要鼠标位于什么屏幕就在哪个屏幕截图,仅需增加一个定时器,在定时器的槽函数中判断当前鼠标的屏幕并重新初始化。(注意根据hasArea判断是否已经取了截图区域)
具体的demo包括DrawingOperationStack(操作栈)、ScreenShotEditArea(截图编辑区)、ScreenShotToolBar(操作栏)三个部分组成。工程我放入了百度网盘中,链接如下:
链接:https://pan.baidu.com/s/1OaHkAlVBiWPx5FU2z3IMrw
提取码:gogo
具体的代码也贴出来:
测试用的widget(拖进来个按钮和label,按钮用于触发截图,label显示图片):
#include "widget.h"
#include "ui_widget.h"
#include
#include
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->hide();
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
QDesktopWidget* deskTop = QApplication::desktop();
int curMonitor = deskTop->screenNumber(this);
st = new QtScreenShot(curMonitor,this);
st->setParent(this);
connect(st,SIGNAL(onScreenShotOK()),this,SLOT(closeScreenShot()));
st->exec();
}
void Widget::closeScreenShot()
{
QImage image = st->getScreenShotImage();
image = image.scaled(ui->label_1->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
QPixmap im = QPixmap::fromImage(image);
ui->label_1->setPixmap(im);
st->accept();
}
drawingoperationstack.h:
#ifndef DRAWINGOPERATIONSTACK_H
#define DRAWINGOPERATIONSTACK_H
#include
#include
#include
struct DrawingOperation{
int curMode;
QRect recogRect;
QRect tempRect;
};
class DrawingOperationStack
{
public:
DrawingOperationStack();
void pushInStack(int curMode, QRect rectr, QRect rectt);
DrawingOperation popStack();
DrawingOperation getCurOperation();
bool isEmptyStack();
private:
QStack stack;
};
#endif // DRAWINGOPERATIONSTACK_H
drawingoperationstack.cpp
#include "drawingoperationstack.h"
#include
DrawingOperationStack::DrawingOperationStack()
{
this->stack.clear();
}
void DrawingOperationStack::pushInStack(int curMode, QRect rectr, QRect rectt)
{
DrawingOperation *st;
st = new DrawingOperation;
st->curMode = curMode;
st->recogRect = rectr;
st->tempRect = rectt;
//qDebug()<mode<rect;
this->stack.push(st);
}
DrawingOperation DrawingOperationStack::popStack()
{
DrawingOperation op;
op.curMode = -1;
op.recogRect = QRect(0,0,0,0);
op.tempRect = QRect(0,0,0,0);
if(this->stack.isEmpty())
{
return op;
}
DrawingOperation *opera = this->stack.pop();
op.recogRect = opera->recogRect;
op.tempRect = opera->tempRect;
op.curMode = opera->curMode;
//this->stack.pop();
delete opera;
//qDebug()<stack.isEmpty())
{
return op;
}
DrawingOperation *opera = this->stack.back();
op.recogRect = opera->recogRect;
op.tempRect = opera->tempRect;
op.curMode = opera->curMode;
return op;
}
bool DrawingOperationStack::isEmptyStack()
{
return this->stack.isEmpty();
}
qtscreenshoteditarea.h
#ifndef QTSCREENSHOTEDITAREA_H
#define QTSCREENSHOTEDITAREA_H
#include
#include
#include "drawingoperationstack.h"
class QtScreenShotEditArea : public QWidget
{
Q_OBJECT
public:
explicit QtScreenShotEditArea(QWidget *parent = nullptr);
void setBgImage(QImage &image);
void paintEvent(QPaintEvent *event);
void setMode(int mode);
void setOpRect(QRect rectR,QRect rectT);
QImage getImage();
protected:
void mousePressEvent(QMouseEvent *e);//鼠标按下事件
void mouseMoveEvent(QMouseEvent *e);//鼠标按下后移动事件
void mouseReleaseEvent(QMouseEvent *e);//鼠标按下后抬起事件
private:
QRect tempRect;
QPoint startPoint;
QRect recogRect;
QImage bgImage;
int curMode;
signals:
void emitOperation(DrawingOperation op);
};
#endif // QTSCREENSHOTEDITAREA_H
qtscreenshoteditarea.cpp
#include "qtscreenshoteditarea.h"
#include
#include
#include
#include
QtScreenShotEditArea::QtScreenShotEditArea(QWidget *parent) : QWidget(parent)
{
this->recogRect = QRect(0,0,0,0);
this->tempRect = QRect(0,0,0,0);
setWindowFlags(windowFlags() | Qt::FramelessWindowHint|Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);
bgImage = QImage(0,0,QImage::Format_RGB32);
setAttribute(Qt::WA_TranslucentBackground, true);
curMode = -1;
}
void QtScreenShotEditArea::setBgImage(QImage &image)
{
this->bgImage = image;
this->update();
}
void QtScreenShotEditArea::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
if(bgImage.size().width() == 0 && bgImage.size().height() == 0)
{
return;
}
QPoint pt(0,0);
QColor recogColor(223,80,80);
QColor tempColor(0,137,255);
painter.drawImage(pt,bgImage);
if(recogRect.width() != 0 && recogRect.height() != 0)
{
QPoint pt1(recogRect.x(),recogRect.y());
QPoint pt2(recogRect.x(),recogRect.y() + recogRect.height());
QPoint pt3(recogRect.x() + recogRect.width(), recogRect.y() + recogRect.height());
QPoint pt4(recogRect.x() + recogRect.width(), recogRect.y());
painter.setPen(QPen(recogColor));
painter.drawLine(pt1,pt2);
painter.drawLine(pt2,pt3);
painter.drawLine(pt3,pt4);
painter.drawLine(pt4,pt1);
}
if(tempRect.width() !=0 &&tempRect.height() != 0)
{
QPoint pt1(tempRect.x(),tempRect.y());
QPoint pt2(tempRect.x(),tempRect.y() + tempRect.height());
QPoint pt3(tempRect.x() + tempRect.width(), tempRect.y() + tempRect.height());
QPoint pt4(tempRect.x() + tempRect.width(), tempRect.y());
painter.setPen(QPen(tempColor));
painter.drawLine(pt1,pt2);
painter.drawLine(pt2,pt3);
painter.drawLine(pt3,pt4);
painter.drawLine(pt4,pt1);
}
}
void QtScreenShotEditArea::setMode(int mode)
{
curMode = mode;
}
void QtScreenShotEditArea::setOpRect(QRect rectR,QRect rectT)
{
this->tempRect = rectT;
this->recogRect = rectR;
//qDebug()<tempRect<recogRect;
this->update();
}
QImage QtScreenShotEditArea::getImage()
{
QImage image;
QPixmap pix;
pix = this->grab(QRect(0,0,this->width(),this->height()));
image = pix.toImage();
return image;
}
void QtScreenShotEditArea::mousePressEvent(QMouseEvent *e)
{
this->startPoint = e->pos();
}
void QtScreenShotEditArea::mouseMoveEvent(QMouseEvent *e)
{
QPoint pt = e->pos();
QRect curRect = QRect(startPoint.x(),startPoint.y(), pt.x() - startPoint.x(), pt.y() - startPoint.y());
if(curMode ==0)
{
this->recogRect = curRect;
}
if(curMode == 1)
{
this->tempRect = curRect;
}
this->update();
}
void QtScreenShotEditArea::mouseReleaseEvent(QMouseEvent *e)
{
QPoint pt = e->pos();
QRect curRect = QRect(startPoint.x(),startPoint.y(), pt.x() - startPoint.x(), pt.y() - startPoint.y());
DrawingOperation op;
op.curMode =curMode;
if(curMode == -1)
{
return;
}
if(curMode ==0)
{
this->recogRect = curRect;
}
if(curMode == 1)
{
this->tempRect = curRect;
}
op.recogRect = this->recogRect;
op.tempRect = this->tempRect;
//qDebug()<update();
}
qtscreenshottoolbar.h
#ifndef QTSCREENSHOTTOOLBAR_H
#define QTSCREENSHOTTOOLBAR_H
#include
#include
#include
class QtScreenShotToolBar : public QWidget
{
Q_OBJECT
public:
explicit QtScreenShotToolBar(QWidget *parent = nullptr);
void setPos(int x, int y);
void setMode(int mode);
void init();
void paintEvent(QPaintEvent *event);
void resetChosen(int num);
protected:
void mouseReleaseEvent(QMouseEvent *e);//鼠标按下后抬起事件
private:
bool bChosen[5];
signals:
void setDrawMode(int mode);
void removeDrawMode(int mode);
};
#endif // QTSCREENSHOTTOOLBAR_H
qtscreenshottoolbar.cpp
#include "qtscreenshottoolbar.h"
#include
#include
#include
QtScreenShotToolBar::QtScreenShotToolBar(QWidget *parent) : QWidget(parent)
{
//this->setGeometry(100,100,100,20);
setWindowFlags(windowFlags() | Qt::FramelessWindowHint|Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);
setAttribute(Qt::WA_TranslucentBackground, true);
this->init();
this->update();
}
void QtScreenShotToolBar::setPos(int x, int y)
{
int curX = x- 100;
if(curX<0)
{
curX = 0;
}
this->setGeometry(curX,y,100,20);
this->update();
}
void QtScreenShotToolBar::setMode(int mode)
{
bChosen[mode] = true;
resetChosen(mode);
qDebug()<update();
}
void QtScreenShotToolBar::init()
{
//this->setGeometry(100,100,100,20);
for(int i=0;i<5;i++)
{
bChosen[i] = false;
}
// this->set
}
void QtScreenShotToolBar::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
qDebug()<<"painting!";
for(int i=0;i<5;i++)
{
qDebug()<pos();
if(pt.y()<0 || pt.y()>20)
{
return;
}
int chosenNum = 0;
if(pt.x() < 0)
{
return;
}
else if(pt.x() < 20)
{
chosenNum = 0;
}
else if(pt.x() < 40)
{
chosenNum = 1;
}
else if(pt.x() < 60)
{
chosenNum = 2;
}
else if(pt.x() < 80)
{
chosenNum = 3;
}
else if(pt.x()<100)
{
chosenNum = 4;
}
else{
return;
}
bChosen[chosenNum] = !bChosen[chosenNum];
if(bChosen[chosenNum] == true)
{
resetChosen(chosenNum);
emit setDrawMode(chosenNum);
}
else
{
resetChosen(chosenNum);
emit removeDrawMode(chosenNum);
}
if(chosenNum > 1)
{
bChosen[chosenNum] = false;
}
this->update();
}
void QtScreenShotToolBar::resetChosen(int num)
{
for(int i=0; i<5;i++)
{
if(i != num)
{
bChosen[i] = false;
}
}
}
qtscreenshot.h
#ifndef QTSCREENSHOT_H
#define QTSCREENSHOT_H
#include
#include
#include
#include
#include
#include
#include "qtscreenshottoolbar.h"
#include "qtscreenshoteditarea.h"
#include "drawingoperationstack.h"
class QtScreenShot :public QDialog
{
Q_OBJECT
public:
public:
explicit QtScreenShot(int curScreen, QWidget* parent = nullptr);
void init(int curScreen);
void ShowToolBar();
void paintEvent(QPaintEvent* event);
QImage getScreenShotImage();
QImage getFullScreenImage();
void closeAll();
bool hasGotImage;
public slots:
void onDrawModeSet(int mode);
void onDrawModeRemove(int mode);
void onGetOperation(DrawingOperation op);
//void reject();
protected:
void mousePressEvent(QMouseEvent* e);//鼠标按下事件
void mouseMoveEvent(QMouseEvent* e);//鼠标按下后移动事件
void mouseReleaseEvent(QMouseEvent* e);//鼠标按下后抬起事件
private:
QScreen* baseScreen;//屏幕截图
QRect selectArea;//选中截图区域大小(相对)
QRect globalSelectArea;
QRect selectTempArea;
QRect globalTempArea;
QRect selectRecogArea;
QRect globalSelectRecogArea;
QtScreenShotToolBar *toolBar;//截图工具栏
QtScreenShotEditArea *editArea;//截图编辑界面
QPoint startPoint;
QPoint startGlobalPoint;
QImage baseImage;
DrawingOperationStack operationStack;
int curMode;
int curScreen;
QImage ansImage;
private:
QImage getSelectImage(int x, int y, int width, int height);
void bindSignalSlots();
QImage AdjustBrightness(QImage Img, int iBrightValue);
void AutoUnOperation(DrawingOperation delOperation, DrawingOperation curOperation);
bool hasArea;
signals:
void onScreenShotOK();
};
#endif // QTSCREENSHOT_H
qtscreenshot.cpp
#include "qtscreenshot.h"
#include
#include
#include
#include
#include
#include
#include
QtScreenShot::QtScreenShot(int curScreen, QWidget* parent) :
QDialog(parent)
{
this->init(curScreen);
}
void QtScreenShot::init(int curScreen)
{
this->selectArea = QRect(-1, -1, -1, -1);
this->selectRecogArea = QRect(-1, -1, -1, -1);
this->selectTempArea = QRect(-1, -1, -1, -1);
QList screens = QGuiApplication::screens();
qDebug() << screens.size();
qDebug() << curScreen;
this->baseScreen = screens.at(curScreen);
QRect rectCurWin = this->baseScreen->geometry();;
qDebug() << rectCurWin;
QSize siz = this->baseScreen->size();
this->setGeometry(rectCurWin);
setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground, true);
this->hasGotImage = false;
this->editArea = new QtScreenShotEditArea(this);
this->editArea->hide();
this->toolBar = new QtScreenShotToolBar(this);
this->toolBar->hide();
this->baseImage = baseScreen->grabWindow(0).toImage();
this->curMode = -1;
this->hasArea = false;
this->bindSignalSlots();
}
void QtScreenShot::bindSignalSlots()
{
connect(toolBar, SIGNAL(setDrawMode(int)), this, SLOT(onDrawModeSet(int)));
connect(toolBar, SIGNAL(removeDrawMode(int)), this, SLOT(onDrawModeRemove(int)));
connect(editArea, SIGNAL(emitOperation(DrawingOperation)), this, SLOT(onGetOperation(DrawingOperation)));
}
QImage QtScreenShot::AdjustBrightness(QImage Img, int iBrightValue)
{
int red, green, blue;
int pixels = Img.width() * Img.height();
unsigned int* data = (unsigned int*)Img.bits();
for (int i = 0; i < pixels; ++i)
{
red = qRed(data[i]) + iBrightValue;
red = (red < 0x00) ? 0x00 : (red > 0xff) ? 0xff : red;
green = qGreen(data[i]) + iBrightValue;
green = (green < 0x00) ? 0x00 : (green > 0xff) ? 0xff : green;
blue = qBlue(data[i]) + iBrightValue;
blue = (blue < 0x00) ? 0x00 : (blue > 0xff) ? 0xff : blue;
data[i] = qRgba(red, green, blue, qAlpha(data[i]));
}
return Img;
}
void QtScreenShot::AutoUnOperation(DrawingOperation delOperation, DrawingOperation curOperation)
{
/**/
/**/
if (delOperation.curMode == -1)
{
this->hasArea = false;
editArea->hide();
toolBar->hide();
}
else
{
/*无论什么操作,先清空*/
/**/
QRect rect(0, 0, 0, 0);
editArea->setOpRect(rect, rect);
editArea->setMode(-1);
/*可还原再还原*/
/**/
if (curOperation.curMode != -1)
{
editArea->setMode(curOperation.curMode);
editArea->setOpRect(curOperation.recogRect, curOperation.tempRect);
this->toolBar->setMode(curOperation.curMode);
}
}
}
void QtScreenShot::ShowToolBar()
{
}
void QtScreenShot::paintEvent(QPaintEvent* event)
{
QPainter painter(this);
QImage image = getFullScreenImage();
image = AdjustBrightness(image, -30);
painter.drawImage(0, 0, image);
}
QImage QtScreenShot::getScreenShotImage()
{
QImage pixmap = this->editArea->getImage();
this->ansImage = pixmap;
return this->ansImage;
}
QImage QtScreenShot::getFullScreenImage()
{
return baseImage;
}
void QtScreenShot::closeAll()
{
while (!operationStack.isEmptyStack())
{
operationStack.popStack();
}
}
void QtScreenShot::onDrawModeSet(int mode)
{
curMode = mode;
if (mode < 0)
{
return;
}
else if (mode < 2)
{
this->editArea->setMode(mode);
}
else if (mode == 2)
{
qDebug() << "in redo ";
DrawingOperation op = operationStack.popStack();
DrawingOperation op2 = operationStack.getCurOperation();
AutoUnOperation(op, op2);
}
else if (mode == 3)
{
emit onScreenShotOK();
}
else if (mode == 4)
{
this->closeAll();
this->accept();
}
else
{
return;
}
}
void QtScreenShot::onDrawModeRemove(int mode)
{
curMode = -1;
if (mode < 0)
{
return;
}
else if (mode < 2)
{
this->editArea->setMode(-1);
}
else if (mode == 2)
{
}
else if (mode == 3)
{
emit onScreenShotOK();
}
else if (mode == 4)
{
}
else
{
return;
}
}
void QtScreenShot::onGetOperation(DrawingOperation op)
{
this->operationStack.pushInStack(op.curMode, op.recogRect, op.tempRect);
}
void QtScreenShot::mousePressEvent(QMouseEvent* e)
{
this->startPoint = e->pos();
this->startGlobalPoint = e->globalPos();
}
void QtScreenShot::mouseMoveEvent(QMouseEvent* e)
{
QPoint curPoint;
curPoint = e->pos();
//qDebug() << "move";
if (hasArea)
{
qDebug() << "return";
return;
}
int posX = startPoint.x();
int posY = startPoint.y();
int posWid = curPoint.x() - startPoint.x();
int posHig = curPoint.y() - startPoint.y();
this->editArea->setGeometry(posX, posY, posWid, posHig);
QImage ima = this->getSelectImage(posX, posY, posWid, posHig);
this->editArea->setBgImage(ima);
this->editArea->show();
//qDebug() << "showarea in move";
}
void QtScreenShot::mouseReleaseEvent(QMouseEvent* e)
{
if (e->button() == Qt::RightButton)
{
closeAll();
this->accept();
return;
}
if (hasArea)
{
qDebug() << "return";
return;
}
QPoint curPoint;
curPoint = e->pos();
int posX = startPoint.x();
int posY = startPoint.y();
int posWid = curPoint.x() - startPoint.x();
int posHig = curPoint.y() - startPoint.y();
QPoint glcurPoint;
glcurPoint = e->globalPos();
this->globalSelectArea.setRect(startGlobalPoint.x(), startGlobalPoint.y(), glcurPoint.x() - startGlobalPoint.x(), glcurPoint.y() - startGlobalPoint.y());
this->editArea->setGeometry(posX, posY, posWid, posHig);
QImage ima = this->getSelectImage(posX, posY, posWid, posHig);
this->editArea->setBgImage(ima);
this->editArea->show();
this->toolBar->setPos(curPoint.x(), curPoint.y());
this->toolBar->show();
this->hasArea = true;
qDebug() << startPoint << curPoint;
qDebug() << "showarea in release";
}
QImage QtScreenShot::getSelectImage(int x, int y, int width, int height)
{
QImage pixmap = baseImage;
return pixmap.copy(x, y, width, height);
}