我们继续来写小玩意,本来写了一个记事本,但是很无奈,功能实在是太多了,细节也需要处理的很多,所以很到一半就没写了,这次我们来写一个截图工具,先来看下UI的实现
我们要实现的功能不多,但是经典
大概就是这五个模块了,其中我们的延时使用的是定时器来实现的,好的,来看下吧!
UI很简单,我们用了一个QLabel来存放图片,下面是一个附加设置的容器QGroupBox,里面的计数器是一个QSpinBox,下面是一个QCheckBox和五个QPushButton
在实际coding之前,先让大家看下头文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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()代表的是当前游标,也就是出现在鼠标的光标处。
好了,最后我们来看下最终的效果图