Qt screen capture

Source: Internet
Author: User

The software implements drag screenshot and top screenshot results, and finally copies them to the clipboard. It can be used for data comparison or other scenarios.

The software running process is: shortcut key-screen capture-> pin-> copy the result.

At the beginning, I didn't pay attention to the memory. screenshots consume a large amount of memory. After optimization, the memory usage is about 4 MB when I am idle.

The following code is used:

#-------------------------------------------------# Ssot.pro# Project created by QtCreator 2013-11-24T11:01:06##-------------------------------------------------QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = SsotTEMPLATE = appSOURCES += main.cpp\        mainwindow.cpp \    ctoplabel.cpp \    aboutdialog.cppHEADERS  += mainwindow.h \    ctoplabel.h \    aboutdialog.hRESOURCES += \    resource.qrcRC_FILE  += \    info.rcOTHER_FILES += \    info.rc \    readme.txt


Mainwindow. h

# Ifndef MAINWINDOW_H # define MAINWINDOW_H # include <QtWidgets> # include <QVector> # include "aboutdialog. h "# include" ctoplabel. h "class MainWindow: public QMainWindow {Q_OBJECTpublic: MainWindow (QWidget * parent = 0 );~ MainWindow (); struct IDStruct {WId; CTopLabel * pTopLabel;}; private: // Tray Icon // register the hotkey void registerGlobalKey (); // start the hotkey id int hotkeyShotBgId; QVector <IDStruct> topLabelList; // initialization tray; void initTray (); // whether bool isshow.// local event bool nativeEvent (const QByteArray & eventType, void * message, long * result); AboutDialog * aboutDialog; QSystemTrayIcon * trayIcon; private slots: // start void hotkeyShotBgReceived (); void clearShots (); public slots: // disable void clearShot (WId I); // set isShotting to false and allow screenshot capture again void allowShot (); // about void doAboutAction (); signals: // start screenshot hotkey press void hotkeyShotBgPressed () ;};# endif // MAINWINDOW_H

Mainwindow. cpp

# Include "mainwindow. h "# include <QDebug> # include" aboutdialog. h "MainWindow: MainWindow (QWidget * parent): QMainWindow (parent) {topLabelList. clear (); isShotting = false; registerGlobalKey (); initTray (); aboutDialog = new AboutDialog; connect (this, SIGNAL (hotkeyShotBgPressed (), SLOT (hotkeyShotBgReceived ())); trayIcon-> showMessage (tr ("pin to v1.0.1"), "the program has been started, press \" Shift + Z \ ", and drag the mouse! "); TrayIcon-> setToolTip (tr (" Press \ "Shift + Z \" and drag the mouse ");} MainWindow ::~ MainWindow () {if (UnregisterHotKey (HWND (this-> winId (), hotkeyShotBgId) {qDebug ("SHIFT + z is unregisted");} clearShots ();} void MainWindow: registerGlobalKey () {hotkeyShotBgId = GlobalAddAtom (L "hotkeyShotBg")-0xC000; if (RegisterHotKey (HWND (this-> winId (), convert, MOD_SHIFT, 0x5A) {qDebug ("SHIFT + z is registered") ;}} bool MainWindow: nativeEvent (const QByteArray & eventType, void * message, Long * result) {if (eventType = "windows_generic_MSG") {// qDebug ("This is windows MSG"); MSG * msg = static_cast <MSG *> (message ); if (msg-> message = WM_HOTKEY) {UINT fuModifiers = (UINT) LOWORD (msg-> lParam); // mode UINT uVirtKey = (UINT) HIWORD (msg-> lParam); // key value // qDebug ("This is HotKey! "); If (fuModifiers = MOD_SHIFT & u1_key = 0x5A) {emit hotkeyShotBgPressed (); qDebug (" SHIFT + Z is Pressed ");} return true ;}} return false;} void MainWindow: hotkeyShotBgReceived () {// if yes, if (! IsShotting) {CTopLabel * fullScreenLabel = new CTopLabel; // used to transmit the window port pointer and WId IDStruct idStruct; idStruct. id = fullScreenLabel-> winId (); idStruct. pTopLabel = fullScreenLabel; topLabelList. append (idStruct); // The connect (fullScreenLabel, SIGNAL (meClosed (WId), this, SLOT (clearShot (WId); connect (fullScreenLabel, SIGNAL (shotted (), this, SLOT (allowShot (); fullScreenLabel-> showFullScreen ();} isshonal = true ;} Void MainWindow: initTray () {trayIcon = new QSystemTrayIcon (this); trayIcon-> setIcon (QIcon (":/icon/resource/icon.png ")); QMenu * trayMenu = new QMenu; QAction * exitAction = new QAction (tr ("exit (& X)"), trayMenu ); QAction * aboutAciton = new QAction (tr ("about (& A)"), trayMenu); QAction * clearAciton = new QAction (tr ("clear (& C )"), trayMenu); trayMenu-> addAction (clearAciton); connect (clearAciton, SIGNAL (triggered (), this, SL OT (clearShots (); trayMenu-> addSeparator (); trayMenu-> addAction (aboutAciton); connect (aboutAciton, SIGNAL (triggered (), this, SLOT (doAboutAction (); trayMenu-> addAction (exitAction); connect (exitAction, SIGNAL (triggered (), this, SLOT (close ())); trayIcon-> setContextMenu (trayMenu); trayIcon-> show ();} void MainWindow: clearShots () {while (topLabelList. count ()> 0) {delete topLabelList. first (). pTopLabel; top LabelList. first (). pTopLabel = NULL; topLabelList. removeFirst () ;}} void MainWindow: clearShot (WId) {qDebug () <id; if (! TopLabelList. empty (); {for (int I = 0; I <topLabelList. count (); I ++) {if (id = topLabelList [I]. id) {// release the memory delete topLabelList [I]. pTopLabel; qDebug () <"is deleted! "; // Prevents the wild pointer topLabelList [I]. pTopLabel = NULL ;}} allowShot () ;}void MainWindow: allowShot () {isShotting = false ;}// void MainWindow: doAboutAction () {qDebug () <"about"; aboutDialog-> setText (":/icon/readme.txt", true); aboutDialog-> setWindowTitle (tr ("about top v1.0.1 ")); aboutDialog-> setLogo (":/icon/resource/about-logo.png "); aboutDialog-> setInfo ("<table border = \" 0 \ "> <tr height = \" 22 \ "> <td width = 270 valign = \" middle \ "> <b> pin to v1.0.1 </B> </td> <a href = \" https://github.com/pansinm/Ssot/ \ "> View Source Code </a> </td> </tr> <tr height = \" 22 \ "> <td width = 300 valign = \" middle \ "> by pansinm </td> <td> pansinm@163.com </td> </tr> </table> "); aboutDialog-> show ();}

Ctoplabel. h

// Screenshot window # ifndef CTOPLABEL_H # define CTOPLABEL_H # include <QtWidgets> class CTopLabel: public QLabel {Q_OBJECTpublic: explicit CTopLabel (QWidget * parent = 0 ); // status enum shotState {initShot, beginShot, finishShot}; // winId void setLabelId (WId) {labelId = id ;}~ CTopLabel (); signals: // void meClosed (WId); // void shotted (); private: int labelId; // full screen Pixmap QPixmap fullScreenPixmap; // pixmap QPixmap resultPixmap; // shotState currentState; // QPoint beginPoint as the starting point of the mouse; // QPoint endPoint as the endPoint; // drag the rectangular QRect shotRect with the mouse; // whether the image is in bool isShot; // left-click whether to press bool isPressed; // drag the QPoint dragPosition; void paintEvent (QPaintEvent *); void mousePressEvent (QMouseEvent * ev); void mouseMoveEvent (QMouseEvent * ev ); void mouseReleaseEvent (QMouseEvent * ev); void mouseDoubleClickEvent (QMouseEvent *) ;};# endif // CTOPLABEL_H

Ctoplabel. cpp

# Include "ctoplabel. h "CTopLabel: CTopLabel (QWidget * parent): QLabel (parent) {setLabelId (this-> winId ()); setAutoFillBackground = \ '# \' "// set the current state to initialize currentState = initShot; // set it to isShot = true; // initialize beginPoint = QPoint (0, 0 ); endPoint = QPoint (); shotRect = QRect (,); // left-click the press status isPressed = false; // initialize the window and drag the dragPosition = QPoint (-1, -1); // set no border, no icons in the taskbar, top setWindowFlags (Qt: frameless=whint | Qt: Tool | Qt: WindowStaysOnTopHint); // capture the screen fullScreenPixmap = QPixmap: grabWindow (QApplication: desktop ()-> winId ();} CTopLabel ::~ CTopLabel () {} void CTopLabel: mousePressEvent (QMouseEvent * ev) {if (ev-> button () = Qt: LeftButton) {isPressed = true; if (isShot) {// changing the status and beginPoint = ev-> pos (); qDebug () <beginPoint. x ();} else {// dragPosition = ev-> globalPos ()-this-> pos () ;}} void CTopLabel: mouseMoveEvent (QMouseEvent * ev) {if (isPressed) {if (isShot) {currentState = beginShot; // when the screenshot is dragged, // qDebug () <"isShot"; endPoint = ev-> pos (); // calculate the area based on the drag position. // upper left corner-> lower right corner if (beginPoint. x () <endPoint. x () & beginPoint. y () <endPoint. y () {shotRect = QRect (beginPoint, endPoint);} // lower left-> upper right else if (beginPoint. x () <endPoint. x () & beginPoint. y ()> endPoint. y () {shotRect = QRect (beginPoint. x (), endPoint. y (), endPoint. x ()-beginPoint. x (), beginPoint. y ()-endPoint. y ();} // upper right-> lower left else if (beginPoint. x ()> endPoint. x () & beginPoint. y () <endPoint. y () {shotRect = QRect (endPoint. x (), beginPoint. y (), beginPoint. x ()-endPoint. x (), endPoint. y ()-beginPoint. y ();} // lower right-> upper left else {shotRect = QRect (endPoint, beginPoint);} update ();} else {// move the move window (ev-> globalPos ()-dragPosition) ;}} void CTopLabel: mouseReleaseEvent (QMouseEvent * ev) {if (ev-> button () = Qt: LeftButton) {endPoint = ev-> pos (); // qDebug () <beginPoint. x () <endPoint. x (); if (isShot) {if (currentState = beginShot) {isShot = false; // change the state currentState = finishShot; // region image respixultmap = fullScreenPixmap. copy (shotRect); fullScreenPixmap. loadFromData (NULL); this-> repaint (); setGeometry (shotRect); emit shotted (); // copy the result to the clipboard QClipboard * clipboard = QApplication: clipboard (); clipboard-> setPixmap (resultPixmap) ;}} else {move (ev-> globalPos ()-dragPosition) ;}} isPressed = false;} void CTopLabel :: mouseDoubleClickEvent (QMouseEvent * e) {if (e-> button () = Qt: LeftButton) {// close the current emit meClosed (labelId);} void CTopLabel :: paintEvent (QPaintEvent *) {QPainter painter (this); painter. setFont (QFont ("simsun", 20); switch (currentState) {case initShot: painter. drawPixmap (0, 0, fullScreenPixmap); painter. setPen (QPen (Qt: blue, 1, Qt: SolidLine, Qt: FlatCap); // set the brush break; case beginShot: painter. drawPixmap (0, 0, fullScreenPixmap); painter. setPen (QPen (Qt: blue, 1, Qt: SolidLine, Qt: FlatCap); // set the paint brush painter. drawRect (shotRect); break; case finishShot: painter. drawPixmap (0, 0, resultPixmap); painter. setPen (QPen (Qt: gray, 1, Qt: SolidLine, Qt: FlatCap); // set the paint brush painter. drawRect (0, 0, resultPixmap. size (). width ()-1, resultPixmap. size (). height ()-1); // result window break ;}}

Aboutdialog. h

// This is a previous template about the dialog box, # ifndef ABOUTDIALOG_H # define ABOUTDIALOG_H # include <QDialog> # include <QLabel> # include <QTextEdit> # include <QString> # include <QPushButton> class AboutDialog: public QDialog {Q_OBJECTpublic: explicit AboutDialog (QWidget * parent = 0); // if it is true, text is the file name, and text files are loaded in the text box) void setText (const QString str, bool isFileName = false); // 370x45 image void setLogo (const QString filename); void setInfo (const QString info ); void setBackground = '# \' "QString styleSheet =" default "); private: QLabel * label_Logo; QLabel * label_Info; QTextEdit * textEdit; QPushButton * btn_confirm; void init (); signals: public slots: void openUrl (QString) ;};# endif // ABOUTDIALOG_H

Aboutdialog. cpp

# Include "aboutdialog. h "# include <QHBoxLayout> # include <QVBoxLayout> # include <QPixmap> # include <q1_topservices> # include <QUrl> # include <QFile> # include <QTextStream> AboutDialog :: aboutDialog (QWidget * parent): QDialog (parent) {init ();} void AboutDialog: init () {// do not click this-> setWindowFlags (Qt :: windowTitleHint | Qt: Drawing); label_Logo = new QLabel; label_Logo-> labels (37); label_Info = new QLabel; label_Info-> setMinimumSize (37); textEdit = new QTextEdit; textEdit-> setMinimumSize (370,115); textEdit-> trim (Qt: ScrollBarAlwaysOff); textEdit-> setReadOnly (true); btn_confirm = new QPushButton ("OK "); latency-> setMinimumSize (); QHBoxLayout * hlayout = new QHBoxLayout; hlayout-> addStretch (); hlayout-> addWidget (latency); hlayout-> setMargin (4 ); optional * vlayout = new layout; vlayout-> addWidget (label_Logo); vlayout-> addWidget (label_Info); vlayout-> addWidget (textEdit); vlayout-> addLayout (hlayout ); vlayout-> setMargin (0); setLayout (vlayout); this-> setMinimumSize (370,254); this-> setMaximumSize (370,254); setBackground (); connect (btn_confirm, SIGNAL (clicked (), this, SLOT (hide ();} void AboutDialog: setLogo (const QString filename) {QPixmap pixmap (filename ); label_Logo-> setPixmap (pixmap);} void AboutDialog: setInfo (const QString info) {label_Info-> setText (info); connect (label_Info, SIGNAL (linkActivated (QString )), this, SLOT (openUrl (QString);} void AboutDialog: setText (const QString str, bool isFileName) {if (isFileName = false) textEdit-> setText (str); else if (isFileName = true) {QFile file (str); if (file. open (QIODevice: ReadOnly | QIODevice: Text) {QTextStream in (& file); QString s; s = in. readAll (); textEdit-> setText (s); file. close () ;}} void AboutDialog: setBackground = \' # \ '"QString styleSheet) {if (styleSheet =" default ") {this-> setStyleSheet ("AboutDialog {background = \ '# \'" 241,255) ;}") ;}else setStyleSheet (styleSheet);} void AboutDialog :: openUrl (QString url) {qw.topservices: openUrl (QUrl ));}

Main. cpp

#include "mainwindow.h"#include <QApplication>int main(int argc, char *argv[]){    QApplication a(argc, argv);    MainWindow w;    //w.show();    return a.exec();}

Resource. qrc

<RCC>    <qresource prefix="/icon">        <file>resource/icon.png</file>        <file>readme.txt</file>        <file>resource/about-logo.png</file>    </qresource></RCC>


The running effect is as follows:

650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131229/1240295935-0.jpg "style =" float: none; "title =" turn on "alt =" 191009885.jpg"/>

650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131229/12402963c-1.jpg "style =" float: none; "title =" right-click the tray menu "alt =" 191012373.jpg"/>

650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131229/1240293348-2.jpg "style =" float: none; "title =" about the dialog box "alt =" 191019827.jpg"/>



  • QPixmap: grabWindow (QApplication: desktop ()-> winId () // capture the entire Screen

  • Use paintEve to draw and drag the rectangle and draw the cut result to the window.

  • Use repaint to repaint the window before adjusting the window size. Otherwise, the window may flash.

  • When closing a window, use delete to delete the memory. Otherwise, the memory will be stacked.

  • After completion, use fullScreenPixmap. loadFromData (NULL) to delete full screen pixmap, which can release several MB of memory.

  • SetWindowFlags (Qt: FramelessWindowHint | Qt: Tool | Qt: WindowStaysOnTopHint); you can set a window without borders, a taskbar icon, and a top window.


Source Code address: https://github.com/pansinm/Ssot

Program: http://url.cn/K89Rrn



 


This article from the "water cainiao" blog, please be sure to keep this source http://cpp51.blog.51cto.com/5346598/1331326

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.