• 近来刚学习Qt4编程,想找个实例练习练习,于是产生了一个想法,就是怎么样做一个文本加密,这样,自己保存的一些文档可以通过软件

生成加密文本,到时候要看的时候,通过自己的软件读取就可以。既然有想法了,那就行动起来吧!

  • 加密解密采用RC4方法,目前只能处理英文文档。
  • 首先介绍一下软件的框架



菜单栏:包括【file】、【edit】、【option】、【help】

  • 【file】下拉菜单包括【new】、【open】、【close】、【save】、【save as】、【exit】
  • 【edit】下拉菜单包括【copy】、【cut】、【paste】、【undo】、【redo】
  • 【option】下拉菜单包括【encrypt】、【decipher】
  • 【help】下拉菜单包括【about】
     
    
   



工具栏:包括【file】、【edit】、【option】、【font】、【list】
  • 【file】栏包括【new】、【open】、【save】、【save as】
  • 【edit】栏包括【copy】、【cut】、【paste】、【undo】、【redo】
  • 【option】栏包括【encrypt】、【decipher】
  • 【font】栏包括【fonttype】、【fontsize】、【bold】、【italic】、【under】、【color】
  • 【list】栏包括【list】、【left】、【center】、【justify】、【right】




编辑区:文本编辑框

状态栏:显示行列





  • 菜单栏的实现举例
菜单栏其实只是对功能函数的一个集合而已,拿【file】菜单举例,它包括【open】【new】【close】等操作,像【open】这样的操作,可以看做是一个函数的动作,
当我们点击这个选项的时候,执行相应的功能。

首先、在头文件中定义一个动作,然后为这个动作添加一个需要执行的槽
private slots:
void open();
private:
QAction* openAction;

其次、就是在**.cpp中创建这个QAction

在这里为了各个QAction的创建和维护的便利性,我定义了一个creatAction()函数,如下是创建openAction的代码:
void SecretMainWindow::creatAction()
{
//=========创建一个【file】->【Open】的动作响应=========//
openAction = new QAction(tr("&Open"), this);
openAction->setIcon(QIcon(":/images/open.png"));
openAction->setShortcut(QKeySequence::Open);
openAction->setStatusTip(tr("Open a file"));
connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
}
openAction = new QAction(tr("&Open"), this);

创建一个新的QAction,标签是【Open】

openAction->setIcon(QIcon(":/images/open.png"));

给【Open】设置一个图标

详见: Qt--创建自定义图标

openAction->setShortcut(QKeySequence::Open);

给【Open】创建一个快捷键【Ctrl + O】

openAction->setStatusTip(tr("Open a file"));

给【Open】设置状态提示

connect(openAction, SIGNAL(triggered()), this, SLOT(open()));

连接信号与槽

然后、creatMenu()函数实现创建


void SecretMainWindow::creatMenus()
{
//=========创建一个【file】菜单栏=========//
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(newAction);
fileMenu->addAction(openAction);
fileMenu->addAction(closeAction);
fileMenu->addAction(saveAction);
fileMenu->addAction(saveAsAction);
fileMenu->addSeparator();
fileMenu->addAction(exitAction);
}
fileMenu = menuBar()->addMenu(tr("&File"));

创建一个【file】菜单,并且命名为【File】

fileMenu->addAction(newAction);

添加【New】到菜单【File】

fileMenu->addSeparator();

添加一个分隔符

最后、实现槽函数open()
void SecretMainWindow::open()
{
//========== 打开一个文件 ==========//
toSave(); //如果内容发生变更,执行保存
fileName = QFileDialog::getOpenFileName(this); //获得要打开的文件的名字
if(!fileName.isEmpty()) //如果文件名不为空,加载文件
{
loadFile(fileName);
}
textEdit->setVisible(true); //文本编辑器可见
}
  • 工具栏的实现举例
工具栏的实现分两种情况,一种是直接添加菜单栏里头的功能,另一种是只有工具栏上才有的一些功能,实现略有差异,下面分别举例说明。

情况一:把菜单栏里功能添加到工具栏,如【open】
void SecretMainWindow::creatToolBars()
{
//=========创建一个【file】工具栏=========//
fileToolBar = addToolBar(tr("&File"));
fileToolBar->addAction(newAction);
fileToolBar->addAction(openAction);
fileToolBar->addSeparator();
fileToolBar->addAction(saveAction);
fileToolBar->addAction(saveAsAction);
}

方法与建立【file】菜单类似。需要在头文件里建立一个工具栏的变量

QToolBar* fileToolBar;

其余创建过程与【file】菜单是一致的。

情况二:创建工具栏特有的功能,如字体Font
//=========创建一个【font】工具栏=========//
fontToolBar = addToolBar(tr("&Font"));
fontstyleLabel = new QLabel(tr("FontType:"));
fontBox = new QFontComboBox;
fontBox->setFontFilters(QFontComboBox::ScalableFonts);
fontToolBar->addWidget(fontstyleLabel);
fontToolBar->addWidget(fontBox);
fontToolBar = addToolBar(tr("&Font"));

在工具栏上添加一个设置字体的工具栏

fontstyleLabel = new QLabel(tr("FontType:"));

新建一个标签:【FontType】

fontBox = new QFontComboBox;

新建一个字体下拉框

fontBox->setFontFilters(QFontComboBox::ScalableFonts);

把字体添加到下拉框

fontToolBar->addWidget(fontstyleLabel);
fontToolBar->addWidget(fontBox);

把标签和下拉框添加到工具栏上

  • 更新状态栏
void SecretMainWindow::creatStatusBar()
{
locationLabel = new QLabel;
locationLabel->setAlignment(Qt::AlignHCenter);
locationLabel->setMinimumSize(locationLabel->sizeHint()); statusBar()->addWidget(locationLabel); connect(textEdit, SIGNAL(cursorPositionChanged()), this, SLOT(updateStatusBar()));
updateStatusBar();
} void SecretMainWindow::updateStatusBar()
{
locationLabel->setText(tr("%1 row %2 col").arg(textEdit->document()->blockCount())
.arg(textEdit->textCursor().columnNumber()));
}
statusBar()->addWidget(locationLabel);

把状态栏标签添加到状态栏上

connect(textEdit, SIGNAL(cursorPositionChanged()), this, SLOT(updateStatusBar()));

当光标位置发生变化的时候,触发更新状态栏

locationLabel->setText(tr("%1 row  %2 col").arg(textEdit->document()->blockCount())
.arg(textEdit->textCursor().columnNumber()));

显示出光标的位置,其中1,2分别对应后面的两个参数

  • 加密解密
void SecretMainWindow::encrypt()
{
//save();
//QFile file(currentFile);
//QTextStream in(&file);
QString text;
text.append(textEdit->toPlainText()); passwordDlg = new PassWord(this);
if(passwordDlg->exec())
{
if(!passwordDlg->password.isNull())
RC4(text, passwordDlg->password);
}
}
text.append(textEdit->toPlainText());

获取编辑区的文档内容

passwordDlg = new PassWord(this);

新建一个弹出窗口,输入加密密钥

passwordDlg->exec()

运行弹出窗口

if(!passwordDlg->password.isNull())
RC4(text, passwordDlg->password);

确定获取到密钥后,进行RC4加密,参考网上的程序。

void SecretMainWindow::RC4(QString in, QString key)
{
int inLen = in.length();
unsigned char* sequence;
sequence = (unsigned char*)qstrdup(in.toAscii().constData()); int keyLen = key.length();
unsigned char* cKey;
cKey = (unsigned char*)qstrdup(key.toAscii().constData()); QString out = ""; //Init Sbox
char SBox[128],Key[128];
int i, k, j = 0, t;
char temp, r; for(i = 0; i < 128; i++)
SBox[i] = i; for(k = i = 0; i < 128; i++)
{
Key[i] = cKey[k];
k = (k + 1) % keyLen;
} for (i = 0; i < 128; i++)
{
j = (j + SBox[i] + Key[i]) % 128;
temp = SBox[i];
SBox[i] = SBox[j];
SBox[j] = temp;
}
//RC4 Cipher
i=0;
j=0;
for(k = 0; k < inLen; k++)
{
r = sequence[k];
i = (i + 1) % 128;
j = (j + SBox[i]) % 128;
temp = SBox[i];
SBox[i] = SBox[j];
SBox[j] = temp;
t = (SBox[i] + SBox[j]) % 128;
r = r ^ SBox[t];
//out += QString::number(r, 16);
out += QString(QChar(r));
//char rr = char(r);
//out += QString::fromUtf8(&rr);
}
textEdit->clear();
textEdit->setText(out);
delete[] sequence;
}

其中,解密就是加密的逆过程,因此可以用同一个函数解密。

void SecretMainWindow::decipher()
{
encrypt();
}
  • 弹出密钥输入窗口

创建一个password类。

#ifndef PASSWORD_H
#define PASSWORD_H #include<QDialog> class QLabel;
class QPushButton;
class QLineEdit; class PassWord:public QDialog
{
Q_OBJECT
public:
PassWord(QWidget* parent = 0);
QString password;
private:
QLabel* passwordLabel;
QLineEdit* passwordLineEdit;
QPushButton* okButton;
QPushButton* cancelButton;
private slots:
void slotOk();
void slotCancel();
//signals:
//getPassword(const QString& password); };
#endif // PASSWORD_H

点击【ok】,获取密码,点击【Cancel】取消操作。

void PassWord::slotOk()
{
password = passwordLineEdit->text();
//emit getPassword(password);
this->accept();
} void PassWord::slotCancel()
{
password = QString::null;
this->reject();
}
  • 效果演示

加密前:

加密后:




  • 程序下载


用VS2008编译,发布release版本

Qt4--加密日记本(子例化QMainWindow文本加密解密)的更多相关文章

  1. QT中实现应用程序的单例化

    一介绍 通过编写一个QSingleApplication类,来实现Qt程序的单例化,原文的作者是在Windows Vista + Qt4.4 下实现的,不过应用在其他平台上是没问题的.(本文是我在ht ...

  2. C语言 · 文本加密

    算法提高 9-2 文本加密   时间限制:1.0s   内存限制:256.0MB      问题描述 先编写函数EncryptChar,按照下述规则将给定的字符c转化(加密)为新的字符:"A ...

  3. Java实现 蓝桥杯 算法提高 文本加密

    算法提高 9-2 文本加密 时间限制:1.0s 内存限制:256.0MB 提交此题 问题描述 先编写函数EncryptChar,按照下述规则将给定的字符c转化(加密)为新的字符:"A&quo ...

  4. ZeroMQ接口函数之 :zmq_z85_encode – 使用Z85算法对一个二进制秘钥进行加密,输出可打印的文本

    ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq-z85-encode zmq_z85_encode(3)          ØMQ Manual - ØMQ/4. ...

  5. 62.在cdc文件上某些例化模块看不到的原因

    比如在顶层文件中,例化了几个模块,综合后打开cdc文件,会在structure/net中少几个例化模块,即看不到,但在顶层文件中还是存在的,只是ISE软件综合的问题而已,原因是在顶层或子模块中,有些应 ...

  6. Quartus中例化工程

    一般的例化工程,需要将要例化的对象的硬件语言放入到当前工程中,比如A要例化B,需要将B的编程文件加入当前工程进来. 还有一种方法不用这么麻烦,A工程用要例化B时,在library添加B的工程路径,就可 ...

  7. AES加密 C++调用Crypto++加密库 样例

    这阵子写了一些数据加密的小程序,对照了好几种算法后,选择了AES,高级加密标准(英语:Advanced Encryption Standard,缩写:AES).听这名字就非常厉害的样子 预计会搜索到这 ...

  8. testbench中$display查看例化model里面信号方法以及$realtime用法

    前言 此为测试语法,不可综合: 流程: 1.在tb中可以这么写,检测clk_t_en的高电平,输出仿真时间位置,想查看的cnt_t是底层模块中的.这么会使得时间延迟一个周期: always @(pos ...

  9. io文本加密

    文本加密习题 package io; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.Inpu ...

随机推荐

  1. Djang DJANGO_SETTINGS_MODULE

    在 site-packages\django 新建一个文件 ’settings.py‘ 内容如下: DEBUG = TrueDEFAULT_FROM_EMAIL = 'alangwansui@qq.c ...

  2. SQL Join PK ChinaJoy

    P PK  

  3. Uva 1354 Mobile Computing

    题目链接 题意: 在一个宽为r 的房间里, 有s个砝码, 每个天平的一端要么挂砝码, 要么挂另一个天平, 并且每个天平要保持平衡. 求使得所有砝码都放在天平上, 且总宽度不超过房间宽度的最大值. 思路 ...

  4. MyEclipse过期激活方法

    如果已经过期会提示,进行购买.重新激活和退出,我们选择重新激活. 打开浏览器,地址栏输入key.858game.com,然后输入名称,在线获得MyEclipse的激活码. 输入Sumscripter: ...

  5. C++的数据类型

    C++的数据类型 计算机处理的对象是数据,而数据是以某种特定的形式存在的(例如整数.浮点数.字符等形式). 不同的数据之间往往还存在某些联系(例如由若干个整数组成一个整数数组).数据结构指的是数据的组 ...

  6. SCOI2015题解 && 考试小结

    Day1: 第一题:裸地二分+网络流:二分答案,连接将每行每列拆成点,对于满足答案的格子行列连边,看是否流量是否大于t即可,可惜第k大看成了第k小,然后100分就没了. 第二题:倍增,考虑贪心算法,就 ...

  7. 【技术贴】解决Program Files文件夹消失

    好久不写程序了,今天良心发现,就寻找一下自己是否安装了JDK,习惯性的去C盘的Program Files的文件夹下面去找,次奥,没有这个文件夹.好吧.是在玩我么. 于是 打开cmd 输入如下命令 AT ...

  8. 系统的了解DJANGO中数据MODULES的相关性引用

    数据库结构如下: from django.db import models class Blog(models.Model): name = models.CharField(max_length=1 ...

  9. 纯js将form表单的数据封装成json 以便于ajax发送

    使用方式: var json = form2Json("formId");//这里的参数是form表单的id值 form2json.js function form2Json(fo ...

  10. BroadCastReceiver中耗时操作导致ANR

    現象:廣播接收器中進行耗時的I/O操作導致ANR. 查資料發現每次广播到来时 , 会重新创建 BroadcastReceiver 对象 , 并且调用 onReceive() 方法 , 执行完以后 该对 ...