cpp文件
#include "vsbak.h"
#include "ui_vsbak.h"
#include <QSettings>
#include <QFileDialog>
#include<QTime>
#include<QtDebug>
#include <QMessageBox>
#define CONFIG_FILE "config.ini"
const QString EXCLUDE_FILE = "/home/hu/project2";// 這個文件沒啥用
Vsbak::Vsbak(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Vsbak)
{
ui->setupUi(this);
QSettings *configIniRead = new QSettings(CONFIG_FILE, QSettings::IniFormat);
dir_src = configIniRead->value("/main/bak_src").toString();
dir_dest = configIniRead->value("/main/bak_dest").toString(); // 配置文件里面有目标地址
gpg_key = configIniRead->value("/main/gpg_key").toString();
exclude_from = configIniRead->value("exclude/exclude").toString();
delete configIniRead;
// init bash terminal
//QProcess可以用于启动外部程序
cmd = new QProcess(this);// 因为与父类直接释放内存
// Sets the working directory to dir. QProcess will start the process in this directory.
//The default behavior is to start the process in the working directory of the calling process.
cmd->setWorkingDirectory(dir_src);
//This signal is emitted when the process has made new data available
//through its standard output channel (stdout). It is emitted regardless of the current read channel.
connect(cmd, &QProcess::readyReadStandardOutput, this, &Vsbak::on_readyReadStandardOutput);
connect(cmd, &QProcess::readyReadStandardError, this, &Vsbak::on_readyReadStandardError);
ui->lineEdit->setText(dir_src);
ui->lineEdit_2->setText(dir_dest); // 在ui里直接设置这个地址
// init comboBox
init_comboBox();
// init radiobutton: choice full
ui->radioButton->setChecked(true);
ui->checkBox->setChecked(false);
ui->checkBox_2->setEnabled(false);
ui->checkBox_3->setEnabled(false);
}
/*
* 设置最大可见数目为5,是不是不合理?
*/
void Vsbak::init_comboBox() // 找压缩好的文件 Combobox 下拉菜单
{
/*
* 1. 用一个对象进入dir-dest目录下
* 2. 过滤掉包含后追的文件
* 3. 获取被过滤的文件理解
*/
// find all backup.tar.gz files
//The QDir class provides access to directory structures and their contents. 不仅能看到结构,还可以看到目录
QDir *curDir = new QDir(dir_dest);
//The QStringList class provides a list of strings.
//可以让你提取一个新的列表只包含这些字符串包含一个特定的字符串(或匹配特定正则表达式)
QStringList filter;
// 过渡成一个目录
filter << "*.tar.gz" << "*.tar.gz.gpg";
curDir->setNameFilters(filter); // 过滤掉特定的目录下的文件
//Returns a list of QFileInfo objects for all the files and directories in the directory
//QDir::entryInfoList()会获取该目录下所有目录和文件的QFileInfo对象的列表
QList<QFileInfo> *tarFileInfo = new QList<QFileInfo>(curDir->entryInfoList(filter));
/*
* dir_dest 里面存放的其实都是被压缩的文件,所以用上面的后缀直接进行过滤
* 1. 设置最大的可见数目为5
* 2. 看目录里面有多少,然后放入这个comboBox
* 3. 获取被过滤的文件
* 4. 按照顺序放入到combobox中
*/
ui->comboBox->clear();
ui->comboBox->setMaxVisibleItems(5); // 最大可见数目 5
//The string will be inserted as the first item in the combobox.
ui->comboBox->setInsertPolicy(QComboBox::InsertAtTop);
for (int i=0; i< tarFileInfo->count(); i++)// count()只是计算里面的数量,tarFileinfo实际上是一个文件列表
ui->comboBox->addItem(tarFileInfo->at(i).fileName());
}
Vsbak::~Vsbak()
{
delete ui;
// 有何作用
if(cmd->state() == QProcess::Running){
cmd->terminate();
cmd->waitForFinished();
}
}
void Vsbak::on_readyReadStandardOutput()
{
// QString out = QString::fromLocal8Bit(cmd->readAllStandardOutput());
// ui->label_4->setText(out);
}
void Vsbak::on_readyReadStandardError()
{
QMessageBox::information(0, "Error", cmd->readAllStandardError());
}
// change dir_src
void Vsbak::on_toolButton_clicked()
{
/*
* 1. 或许dir_src的文件目录名称
* 2. 将dir_src的文件目录名写到lineEdit上面
* 3. 更新配置文件里面的信息
* 4. 设置工作目录
*
*/
QString dirname;
dirname = QFileDialog::getExistingDirectory(this, tr("Open Directory"), dir_src, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if(dirname.isEmpty()) return;
else {
dir_src = dirname;
ui->lineEdit->setText(dir_src);
QSettings *configIniWrite = new QSettings(CONFIG_FILE, QSettings::IniFormat);
configIniWrite->setValue("/main/bak_src", dir_src);
delete configIniWrite;
cmd->setWorkingDirectory(dir_src);
ui->label_4->setText("change source dir sucess!");
}
}
// change dir_dest
void Vsbak::on_toolButton_2_clicked()
{
QString dirname;
// getExistingDirectory 只获取文件夹
dirname = QFileDialog::getExistingDirectory(this, tr("Open Directory"), dir_dest, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if(dirname.isEmpty()) return;
else {
dir_dest = dirname;
ui->lineEdit_2->setText(dir_dest);
QSettings *configIniWrite = new QSettings(CONFIG_FILE, QSettings::IniFormat);
configIniWrite->setValue("/main/bak_dest", dir_dest);
delete configIniWrite;
ui->label_4->setText("change dest dir sucess!");
}
}
int Vsbak::get_min(QDateTime curTime)
{
QSettings *configIniReadWrite = new QSettings(CONFIG_FILE, QSettings::IniFormat);
int lastTime = configIniReadWrite->value("/main/last_time").toInt();// 将值转化成整形
configIniReadWrite->setValue("/main/last_time", curTime.toTime_t());
delete configIniReadWrite;
int minDiff = (curTime.toTime_t()-lastTime) / 60 + 1;
return minDiff;
}
void Vsbak::on_checkBox_clicked()
{
if(ui->checkBox->isChecked()){
ui->checkBox_2->setEnabled(true);
ui->checkBox_3->setEnabled(true);
}
else{
ui->checkBox_2->setEnabled(false);
ui->checkBox_3->setEnabled(false);
}
}
/*
* 3 个 String类型
* targz:time + full.tar.gz
* cmd_find:find ./ -type f | grep -v \'Permission denied\' > TEPLIST
* cmd_tar
*目录列表
*
*
*
*/
void Vsbak::on_pushButton_clicked(){
// The QDateTime class provides date and time functions.
// 调用QDatetime里面的一个函数,赋给另一个QDatetime的类型
QDateTime current_date_time = QDateTime::currentDateTime();
// 初始化三个String类型
QString targz, cmd_find, cmd_tar;
//RadioButton presents an option button that can be toggled on (checked) or off (unchecked).
//Radio buttons are typically used to select one option from a set of options.
//Use isChecked() to see if a particular button is selected.
if(ui->radioButton->isChecked()){ // 如果radiobutton 被选择了,那么就进行备份,如果没有就只输出时间
// Linux find命令用来在指定目录下查找文件。
// 将目前目录其其下子目录中所有一般文件列出 # find . -type f
// Linux grep 命令用于查找文件里符合条件的字符串。
// -v 或 --revert-match : 显示不包含匹配文本的所有行。
// 反向查找。前面各个例子是查找并打印出符合条件的行,通过"-v"参数可以打印出不符合条件行的内容。
// ./ 表示当前目录的全路径 当前目录的全路径 没有这个 \'Permission denied\'????
//linux的命令,查找文件然后设置权限
// 这个是不管修改不修改,全部列出来
cmd_find = "find ./ -type f | grep -v \'Permission denied\' > TEPLIST";// 这个功能是什么呢
targz = current_date_time.toString("yyyy-MM-dd_hh.mm.ss") + ".full.tar.gz";
}else{
// 会替换掉前面的百分之1,替换规则是从小到大
//get_min是一个函数,看它具体怎么实现的,应该是循环遍历了current_date_time,找到最小????
int minDiff = get_min(current_date_time); // 获得是最小的查值
// 完成命令,把距离最新一次全部修改的文件单独列出来
cmd_find = QString("find ./ -mmin -%1 -type f | grep -v \'Permission denied\' > TEPLIST").arg(minDiff);
targz = current_date_time.toString("yyyy-MM-dd_hh.mm.ss") + ".inc.tar.gz";
}
// exclude from 是一个配置目录
// tar命令
//-v或--verbose 显示指令执行过程
// --totals 备份文件建立后,列出文件大小
//cmd_tar这是压缩tar的linux命令,将exclude里面的文件全部列出来,进行压缩
cmd_tar = QString("tar --verbose --totals --exclude-vcs %1 --files-from=TEPLIST -czf %2/%3").arg(exclude_from).arg(dir_dest).arg(targz);//?5
// 向调试器输出命令的执行结果,方便调试排错
qDebug()<< cmd_find << endl << cmd_tar<< endl;
// 下面整个过程就是执行这个命令
QStringList cmd_pipe;// 初始化了一个String目录
cmd_pipe << "-c" << cmd_find; // 说明这个cmd-pipe已经变成了一个linux的cmd命令了
cmd->start("/bin/bash",cmd_pipe); // 开始一个程序
cmd->waitForFinished();
cmd->close();
cmd->start(cmd_tar);// cmd_tar 也变成了一个程序
cmd->waitForFinished();
cmd->close();
cmd->start("rm -f TEPLIST");// 强制删除teplist, teplist 就是临时文件
cmd->waitForFinished();
/*********** Encrypting*************/
// gpg-k 增加公共钥匙
if(ui->checkBox->isChecked()){
QString cmd_enc;
QString cmd_isKey = "gpg -k " + gpg_key;
cmd->start(cmd_isKey);
cmd->waitForFinished();
QString out = QString::fromLocal8Bit(cmd->readAllStandardOutput());// 这个输出就不是很理解为什么
if(out.isEmpty())
// -o, --output FILE write output to FILE
// c 说是使用对称加密,看起来很奇怪
cmd_enc = QString("gpg -c -o %1/%2.gpg %1/%2").arg(dir_dest).arg(targz);
else
// e 是加密数据 , 针对 用户 id 进行加密
cmd_enc = QString("gpg -e -r %1 -o %2/%3.gpg %2/%3").arg(gpg_key).arg(dir_dest).arg(targz);
cmd->start(cmd_enc);
cmd->waitForFinished();
if(false == ui->checkBox_2->isChecked()){
QString cmd_rm = QString("rm %1/%2.gpg").arg(dir_dest).arg(targz);
cmd->start(cmd_rm);
cmd->waitForFinished();
}
if(false == ui->checkBox_3->isChecked()){
QString cmd_rm = QString("rm %1/%2").arg(dir_dest).arg(targz);
cmd->start(cmd_rm);
cmd->waitForFinished();
}
/*
* /home/hu/桌面/vsbak/backup/2019-11-13_19.38.57.full.tar.gz
*
*/
// ui->comboBox->addItem(targz);
init_comboBox();
}
}
void Vsbak::on_pushButton_2_clicked(){
QString targz = ui->comboBox->currentText();
if (targz.endsWith(".tar.gz.gpg")){
targz = targz.remove(".gpg");
QString cmd_enc;
QString cmd_isKey = "gpg -k " + gpg_key;
cmd->start(cmd_isKey);
cmd->waitForFinished();
QString out = QString::fromLocal8Bit(cmd->readAllStandardOutput());
if(out.isEmpty())
cmd_enc = QString("gpg -d -o %1/%2 %1/%2.gpg").arg(dir_dest).arg(targz);
else
cmd_enc = QString("gpg -d -r %1 -o %2/%3 %2/%3.gpg").arg(gpg_key).arg(dir_dest).arg(targz);
cmd->start(cmd_enc);
cmd->waitForFinished();
}
QString cmd_str = QString("tar -xvf %1/%2").arg(dir_dest).arg(targz);
qDebug() << cmd_str;
cmd->start(cmd_str);
cmd->waitForFinished();
}
上面是cpp文件
下面是
h文件
#ifndef VSBAK_H
#define VSBAK_H
#include
#include
QT_BEGIN_NAMESPACE
namespace Ui { class Vsbak; }
QT_END_NAMESPACE
class Vsbak : public QWidget
{
Q_OBJECT
public:
Vsbak(QWidget *parent = nullptr);
~Vsbak();
private slots:
void on_readyReadStandardOutput();
void on_readyReadStandardError();
void on_toolButton_clicked();
void on_toolButton_2_clicked();
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_checkBox_clicked();
private:
Ui::Vsbak *ui;
QProcess *cmd;
QString dir_dest;
QString dir_src;
QString gpg_key;
QString exclude_from;
void init_comboBox();
int get_min(QDateTime curTime);// 获得整形
};
#endif // VSBAK_H
我运行之后出来的qt界面,原本是可以下拉选择的,但是都没有反映,这是为啥