QT開發(十一)——專案實戰:截圖工具
我們繼續來寫小玩意,本來寫了一個記事本,但是很無奈,功能實在是太多了,細節也需要處理的很多,所以很到一半就沒寫了,這次我們來寫一個截圖工具,先來看下UI的實現
我們要實現的功能不多,但是經典
- 1.新建截圖(全屏)
- 2.儲存截圖
- 3.複製圖片到系統貼上板
- 4.實時預覽桌面
- 5.右鍵選單的實現
大概就是這五個模組了,其中我們的延時使用的是定時器來實現的,好的,來看下吧!
一.UI
UI很簡單,我們用了一個QLabel來存放圖片,下面是一個附加設定的容器QGroupBox,裡面的計數器是一個QSpinBox,下面是一個QCheckBox和五個QPushButton
在實際coding之前,先讓大家看下標頭檔案
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTimer>
#include <QPixmap>
#include <QDesktopWidget>
#include <QDesktopServices>
#include <QFileDialog>
#include <QClipboard>
#include <QStandardPaths>
#include <QContextMenuEvent>
#include <QMenu>
#include <QAction>
#include <QCursor>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void shotSlot();
void shotVideoSlot();
void on_btn_new_clicked();
void on_btn_save_clicked();
void on_btn_copy_clicked();
void on_btn_video_clicked();
void on_btn_exit_clicked();
protected:
void contextMenuEvent(QContextMenuEvent*);
private:
Ui::MainWindow *ui;
QTimer* timer;
QTimer* timerVideo;
QPixmap pixmap;
};
#endif // MAINWINDOW_H
好的,我們一個個來實現
二.新建截圖
//new
void MainWindow::on_btn_new_clicked()
{
timer = new QTimer;
connect(this->timer,SIGNAL(timeout()),this,SLOT(shotSlot()));
if(this->ui->checkBox->isChecked())
{
this->hide();
timer->start(this->ui->spinBox->value() * 1000);
}
else
{
timer->start(0);
}
}
我們直接來看下程式碼的實現,這裡建立了一個計時器,然後連線了一個shotSlot的槽,接著我會判斷你有沒有勾選延時的按鈕,如果你勾選了,我就去獲取你輸入的延時數字並且隱藏一下視窗,否則我預設0也就是不延時去呼叫shotSlot,所以這裡可以看出,我們的截圖實際上是在shotSlot裡面處理的
//shots
void MainWindow::shotSlot()
{
//當前ID
pixmap = QPixmap::grabWindow(QApplication::desktop()->winId());
//按比例縮放
this->ui->tv_display->setPixmap(this->pixmap.scaled(this->ui->tv_display->size()));
this->show();
this->timer->stop();
}
這裡我直接通過grabWindow獲取到了當前的id來截圖,並且按照QLabel的比例進行設定,然後顯示視窗並且停止計時器,效果和上面的截圖是一樣的
三.儲存截圖
儲存截圖就很簡單了
//save
void MainWindow::on_btn_save_clicked()
{
QString path = QFileDialog::getSaveFileName(this,"儲存檔案",QStandardPaths::writableLocation(QStandardPaths::DesktopLocation));
this->pixmap.save(path);
}
呼叫一個QPixmap的save方法即可,這裡QFileDialog跳轉到桌面,然後儲存就好
三.複製截圖
//copy
void MainWindow::on_btn_copy_clicked()
{
QClipboard* clip = QApplication::clipboard();
clip->setPixmap(this->pixmap);
}
複製截圖就是把圖片複製到系統貼上板,用到的是QClipboard
四.實時預覽
實時的預覽這其實是使用了一點技巧,先看程式碼
//video
void MainWindow::on_btn_video_clicked()
{
QString btnText = this->ui->btn_video->text();
//如果當前是關閉的
if(btnText == "實時預覽:OFF")
{
this->ui->btn_video->setText("實時預覽:ON");
timerVideo = new QTimer;
connect(this->timerVideo,SIGNAL(timeout()),this,SLOT(shotVideoSlot()));
timerVideo->start(1000 / 24);
}
else
{
this->ui->btn_video->setText("實時預覽:OFF");
this->timerVideo->stop();
}
}
我打開了預覽的話就是啟動了一個計時器然後每隔1000/24ms就去呼叫shotVideoSlot,關閉就是停止計時器
//shots video
void MainWindow::shotVideoSlot()
{
pixmap = QPixmap::grabWindow(QApplication::desktop()->winId());
//按比例縮放
this->ui->tv_display->setPixmap(this->pixmap.scaled(this->ui->tv_display->size()));
}
你會發現,實際上我是一直不斷的去截圖來實現桌面預覽的,最後就是我們的選單了
五.選單
我們右鍵可以看到會出現兩個選項,這就是我們自定義的右鍵選單了
//right menu
void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
//建立選單
QMenu*menu =new QMenu;
QAction*action = new QAction(this);
action->setText("複製");
QAction*action1 = new QAction(this);
action1->setText("另存為");
//連線兩個槽
connect(action,SIGNAL(triggered(bool)),this,SLOT(on_btn_copy_clicked()));
connect(action1,SIGNAL(triggered(bool)),this,SLOT(on_btn_save_clicked()));
menu->addAction(action);
menu->addAction(action1);
menu->exec(QCursor::pos());
}
建立的方法很簡單,一個QMenu,一個QAction響應,這裡要注意的是最後一句:menu->exec(QCursor::pos());,這裡面的QCursor::pos()代表的是當前遊標,也就是出現在滑鼠的游標處。
好了,最後我們來看下最終的效果圖