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