如果某次編碼結果不錯,我們往後想要繼續利用同一個 Encrypt 物件,這時候就需要把 Encrypt 物件儲存下來。想一想我們存檔應該儲存什麼?把整個 Encrypt 物件都儲存下來,還是只要儲存編碼用的 cArray 就可以了呢?
簡單一點,就儲存 cArray 就可以了,只是這樣 Encrypt 類別 (class) 需要多一個 setcArray() ,直接以載入的 cArray ,也就是用字串 (string) 當參數 (parameter) 設定 GUIDemo 類別的 e 。
這不難,增加一個 setcArray() 就夠了,因此 Encrypt.h 要加進以下函數成員的宣告
void setcArray(string);
然後 Encrypt.cpp 也要實作 setcArray(string)
void Encrypt::setcArray(string s) { cArray = s; }
記得 Encrypt.h 跟 Encrypt.cpp 都要作修改。接下來看到存檔的 saveEncrypt() 與載入用的 loadEncrypt() ,我們要在 GUIDemo.h 加入這兩個函數成員的宣告,修改過後的 GUIDemo.h 如下
#ifndef GUIDEMO_H #define GUIDEMO_H #include <QWidget> #include "Encrypt.h" class QLabel; class QLineEdit; class QPushButton; class GUIDemo : public QWidget { Q_OBJECT public: GUIDemo(QWidget *parent = 0); QString s2q(const string &); string q2s(const QString &); public slots: void newEncrypt(); void loadEncrypt(); void saveEncrypt(); void encodeContact(); void decodeContact(); void inputContact(); private: QLabel *display; QLineEdit *inputField; QLineEdit *outputField; QPushButton *newButton; QPushButton *loadButton; QPushButton *saveButton; QPushButton *encodeButton; QPushButton *decodeButton; QPushButton *clearButton; QPushButton *copyButton; QString inputText; QString outputText; Encrypt *e; }; #endif /* 《程式語言教學誌》的範例程式 http://pydoing.blogspot.com/ 檔名:GUIDemo.h 功能:示範 C++ 程式 作者:張凱慶 時間:西元 2012 年 10 月 */
實做 saveEncrypt() 與 loadEncrypt() 需要用到 QFile 與 QDataStream ,因此 GUIDemo.cpp 的開頭要先引入這兩個程式庫 (library)
#include <QFile> #include <QDataStream>
saveEncrypt() 如下,當然,如果已經建立 e 才會儲存,如果沒有按過 New 按鈕,就會顯示提示訊息,然後什麼都不會做
void GUIDemo::saveEncrypt() { if (e != NULL) { QFile file("encryptor"); file.open(QIODevice::WriteOnly); QDataStream out(&file); out << s2q(e->getcArray()); display->setText("This is Save button. Encrypt object is saved."); } else { display->setText("This is Save button. There is no Encrypt Object."); } }
存檔過程先是建立 QFile 型態的檔案處理物件 file ,檔名設定為 "encryptor" ,然後呼叫 open() 設定為寫入資料,接著建立 QDataStream 型態的資料串流處理物件 out ,最後以輸出串流運算子將 e 的 cArray 轉換成 QString 儲存到檔案中。
這裡要留意
QDataStream out(&file);
& 為取址運算子,這會取得 file 的記憶體位址,也就是指標 (pointer) 。
loadEncrypt() 的設計雷同,會先判斷 encryptor 檔案是否存在,檔案存在才會繼續進行載入的動作,如果沒有檔案,也就是之前使用沒有按過 Save 按鈕,同樣顯示提示訊息,然後什麼都不會做
void GUIDemo::loadEncrypt() { QFile file("encryptor"); if (file.open(QIODevice::ReadOnly)) { QDataStream in(&file); QString temp; in >> temp; if (e == NULL) { e = new Encrypt; e->setcArray(q2s(temp)); } else { e->setcArray(q2s(temp)); } display->setText("This is Load button. Encrypt object is loaded."); } else { display->setText("This is Load button. Encrypt object is not loaded."); } }
載入過程先是建立 QFile 型態的檔案處理物件 file ,檔名預設為 "encryptor" ,然後呼叫 open() 設定為唯讀,接著建立 QDataStream 型態的資料串流處理物件 in ,最後以輸入串流運算子讀取 QString ,最後將 QString 轉換為 string 設定給 e 的 cArray 。
完整的實作檔 GUIDemo.cpp 如下,記得要把 Save 、 Load 兩個按鈕建立 connect
#include <QtGui> #include "GUIDemo.h" #include <QFile> #include <QDataStream> GUIDemo::GUIDemo(QWidget *parent) : QWidget(parent) { QLabel *input = new QLabel(tr("Input:")); QLabel *output = new QLabel(tr("Output:")); display = new QLabel(tr("something happened")); inputField = new QLineEdit; connect(inputField, SIGNAL(returnPressed()), this, SLOT(inputContact())); outputField = new QLineEdit; outputField->setReadOnly(true); newButton = new QPushButton(tr("New")); connect(newButton, SIGNAL(clicked()), this, SLOT(newEncrypt())); loadButton = new QPushButton(tr("Load")); connect(loadButton, SIGNAL(clicked()), this, SLOT(loadEncrypt())); saveButton = new QPushButton(tr("Save")); connect(saveButton, SIGNAL(clicked()), this, SLOT(saveEncrypt())); encodeButton = new QPushButton(tr("Encode")); connect(encodeButton, SIGNAL(clicked()), this, SLOT(encodeContact())); decodeButton = new QPushButton(tr("Decode")); connect(decodeButton, SIGNAL(clicked()), this, SLOT(decodeContact())); clearButton = new QPushButton(tr("Clear")); copyButton = new QPushButton(tr("Copy")); QGridLayout *layout = new QGridLayout; layout->addWidget(input, 0, 0); layout->addWidget(inputField, 0, 1, 1, 6, 0); layout->addWidget(output, 1, 0); layout->addWidget(outputField, 1, 1, 1, 6, 0); layout->addWidget(newButton, 2, 0); layout->addWidget(loadButton, 2, 1); layout->addWidget(saveButton, 2, 2); layout->addWidget(encodeButton, 2, 3); layout->addWidget(decodeButton, 2, 4); layout->addWidget(clearButton, 2, 5); layout->addWidget(copyButton, 2, 6); layout->addWidget(display, 3, 0, 1, 7, 0); setLayout(layout); setWindowTitle(tr("GUIDemo")); e = NULL; } void GUIDemo::newEncrypt() { e = new Encrypt; display->setText("This is New button. Encrypt code is " + s2q(e->getcArray())); } void GUIDemo::loadEncrypt() { QFile file("encryptor"); if (file.open(QIODevice::ReadOnly)) { QDataStream in(&file); QString temp; in >> temp; if (e == NULL) { e = new Encrypt; e->setcArray(q2s(temp)); } else { e->setcArray(q2s(temp)); } display->setText("This is Load button. Encrypt object is loaded."); } else { display->setText("This is Load button. Encrypt object is not loaded."); } } void GUIDemo::saveEncrypt() { if (e != NULL) { QFile file("encryptor"); file.open(QIODevice::WriteOnly); QDataStream out(&file); out << s2q(e->getcArray()); display->setText("This is Save button. Encrypt object is saved."); } else { display->setText("This is Save button. There is no Encrypt Object."); } } void GUIDemo::encodeContact() { inputText = inputField->text(); if (inputText == "") { display->setText("This is Encode button. No input string!!"); } else { if (e == NULL) { display->setText("This is Encode button. No Encrypt object!!"); } else { outputText = s2q(e->toEncode(q2s(inputText))); outputField->setText(outputText); display->setText("This is Encode button. The result is above."); } } } void GUIDemo::decodeContact() { inputText = inputField->text(); if (inputText == "") { display->setText("This is Encode button. No input string!!"); } else { if (e == NULL) { display->setText("This is Encode button. No Encrypt object!!"); } else { outputText = s2q(e->toDecode(q2s(inputText))); outputField->setText(outputText); display->setText("This is Decode button. The result is above."); } } } void GUIDemo::inputContact() { inputText = inputField->text(); display->setText("Your input is '" + inputText + "'."); } QString GUIDemo::s2q(const string &s) { return QString(QString::fromLocal8Bit(s.c_str())); } string GUIDemo::q2s(const QString &s) { return string((const char *)s.toLocal8Bit()); } /* 《程式語言教學誌》的範例程式 http://pydoing.blogspot.com/ 檔名:GUIDemo.cpp 功能:示範 C++ 程式 作者:張凱慶 時間:西元 2012 年 10 月 */
重新編譯執行,先建立一個 Encrypt ,下面是編碼結果,然後按 Save
換成其他的 Encrypt ,新的編碼結果
按 Load 載入,會得到儲存 Encrypt 的編碼結果囉
好了,下面我們繼續把功能建置完成,來看看完成版的 GUIDemo 吧!
中英文術語對照 | |
---|---|
物件 | object |
變數成員 | variable member |
函數成員 | function member |
類別 | class |
字串 | string |
參數 | parameter |
程式庫 | library |
指標 | pointer |
您可以繼續參考
GUI 篇
相關目錄
回 C++ 入門指南
回 C++ 教材目錄
回首頁
參考資料
Qt Developer Network
沒有留言:
張貼留言