我開發了自己的混合流密碼,並且對於我使用Qt的GUI。最初我在一個線程上編寫它,但它是一個流密碼,使得在大文件上操作時GUI功能失常。所以我把加密/解密轉移到一個單獨的Qthread。另外爲了顯示我在GUI上包含標準QProgressbar的進度。但是當我運行File I/O時,加密/解密完美地工作,但進度條不能正確更新。整個操作完成後,進度條突然從0%變爲100%,表明在操作過程中沒有得到更新的機會。對於代碼,我將完成百分比從FileCrypto發送到主GUI線程到QProgressbar的setValue(int)插槽中。由於它不起作用,我還嘗試將int poitner發送到FileCrypto線程,同時用百分比更新指針並在GUI線程上使用QTimer在本地檢查int值的值並更新進度欄,但仍然我得到了完全相同的結果。從不同的線程中更新QProgressbar
這裏是我的代碼:
的FileCrypto類:
#include <QThread>
#include <QFile>
#include <PolyVernam.h> //my algo header
class FileCrypto : public QThread
{
Q_OBJECT
public:
FileCrypto(QString, QString, int);
bool stopIt;
protected:
void run();
signals:
void completed(int);
void msg(QString);
void pathMsg1(QString);
void pathMsg2(QString);
void keyMsg(QString);
private:
QFile src, dest;
QString tag;
int mode;
qint64 length;
PolyVernam pv;
};
驗證碼:
#include <FileCrypto.h>
FileCrypto::FileCrypto(QString input, QString keyFile, int mode)
{
stopIt = false;
this->mode = mode;
src.setFileName(input);
if(mode == 1)
{
emit msg("Current Encryption/Decryption status: Encrypting file... :D:D");
tag = "-encrypted";
pv.setMode("encrypt", "");
}
else
{
emit msg("Current Encryption/Decryption status: Decrypting file... :D:D");
tag = "-decrypted";
pv.setMode("decrypt", keyFile);
}
dest.setFileName(QFileInfo(src).absolutePath() + "/" + QFileInfo(src).baseName()
+ tag + "." + QFileInfo(src).completeSuffix());
length = src.bytesAvailable();
}
void FileCrypto::run()
{
qint64 done = 0;
quint8 r, outChar;
char ch;
QDataStream in(&src);
in.setVersion(QDataStream::Qt_4_7);
src.open(QIODevice::ReadOnly);
QDataStream out(&dest);
out.setVersion(QDataStream::Qt_4_7);
dest.open(QIODevice::WriteOnly);
while(!in.atEnd() && !stopIt)
{
done++;
in >> r;
ch = char(r);
if(mode == 1)
outChar = pv.encrypt(QString(ch)).at(0).toAscii();
else
outChar = pv.decrypt(QString(ch)).at(0).toAscii();
out << outChar;
emit completed(int((done/length) * 100));
}
src.close();
dest.close();
if(stopIt)
this->exit(0);
if(mode == 1)
{
emit pathMsg1(QFileInfo(src).absoluteFilePath());
emit pathMsg2(QFileInfo(dest).absoluteFilePath());
}
else
{
emit pathMsg1(QFileInfo(dest).absoluteFilePath());
emit pathMsg2(QFileInfo(src).absoluteFilePath());
}
emit keyMsg(pv.keyFilePath);
emit msg("Current Encryption/Decryption status: Idle... :'(");
}
這是我想提出的線程,它的主界面線程的連接:
FileCrypto *fc = new FileCrypto(ui->lineEdit_4->text(), "", 1);
connect(fc, SIGNAL(completed(int)), ui->progressBar, SLOT(setValue(int)));
connect(fc, SIGNAL(msg(QString)), ui->statusBar, SLOT(showMessage(QString)));
connect(fc, SIGNAL(pathMsg1(QString)), ui->lineEdit_4, SLOT(setText(QString)));
connect(fc, SIGNAL(pathMsg2(QString)), ui->lineEdit_5, SLOT(setText(QString)));
connect(fc, SIGNAL(keyMsg(QString)), ui->lineEdit_2, SLOT(setText(QString)));
connect(fc, SIGNAL(keyMsg(QString)), this, SLOT(done()));
如果我不更新進度條,即不發送百分比,則進程發生得更快。我也嘗試打印百分比。它會像地獄一樣慢下來,但價值很好。也可以爲您建議的方式將其更改爲緩衝IO ....
任何形式的幫助是非常感謝這裏.......
IIRC Qt插槽是同步的。請參閱http://stackoverflow.com/questions/1264887/qt-4-5-is-emitting-signal-a-function-call-or-a-thread-and-does-it-blocks甚至更好的http:/ /cdumez.blogspot.de/2011/03/worker-thread-in-qt-using-signals-slots.html – RedX
正常的方法... 經過上述連接, fc-> start(); 多數民衆贊成在它... –
你有一個'FileToPlay'的構造函數中的'moveToThread()'調用? – Chris