• Qt4--加密日记本(子例化QMainWindow文本加密解密)


     

    • 近来刚学习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版本

  • 相关阅读:
    [Leetcode] generate parentheses 生成括号
    [Leetcode] letter combinations of a phone number 电话号码的字母组合
    MySQL安装出现“不是内部或外部命令,也不是可执行程序”等一系列问题的解决方案
    [Leetcode] sudoku solver 求解数独
    [Leetcode] valid sudoku 有效数独
    jQuery使用(七):事件绑定与取消,及自定事件的实现原理
    前端交互体验核心之事件(一)
    jQuery使用(六):DOM操作之元素包裹、克隆DOM与data的综合应用
    jQuery使用(五):DOM操作之插入和删除元素
    jQuery使用(四):DOM操作之查找兄弟元素和父级元素
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3181575.html
Copyright © 2020-2023  润新知