File 从不同的线程升级QProgressbar
我已经开发了自己的混合流密码,并且正在使用Qt作为GUI。最初我是在一个线程上编写的,但它是一个流密码,这使得GUI在处理大文件时无法正常工作。因此,我将加密/解密转移到一个单独的Qthread。为了显示进度,我在GUI上添加了一个标准的QProgressbar。但是当我运行文件I/O时,加密/解密工作正常,但是进度条没有正确更新。整个操作完成后,进度条突然从0%变为100%,表明在操作过程中没有机会进行更新。对于代码,我将完成百分比从FileCrypto发送到QProgressbar的setValue(int)插槽的主GUI线程。由于它不起作用,我还尝试向FileCrypto线程发送一个int poitner,同时使用百分比更新指针,并在GUI线程上使用QTimer在本地检查int值的值并更新进度条,但仍然得到了完全相同的结果 这是我的密码: FileCrypto类:File 从不同的线程升级QProgressbar,file,qt,cryptography,qthread,qprogressbar,File,Qt,Cryptography,Qthread,Qprogressbar,我已经开发了自己的混合流密码,并且正在使用Qt作为GUI。最初我是在一个线程上编写的,但它是一个流密码,这使得GUI在处理大文件时无法正常工作。因此,我将加密/解密转移到一个单独的Qthread。为了显示进度,我在GUI上添加了一个标准的QProgressbar。但是当我运行文件I/O时,加密/解密工作正常,但是进度条没有正确更新。整个操作完成后,进度条突然从0%变为100%,表明在操作过程中没有机会进行更新。对于代码,我将完成百分比从FileCrypto发送到QProgressbar的setV
#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;
};
如果我不更新进度条,即不发出百分比,则过程会更快。我还试着打印百分比。它会减慢速度,但数值很好。您还可以建议一种将其更改为缓冲IO的方法
这里非常感谢您提供的任何帮助……问题不在于您是从不同的线程呼叫的。它位于:
emit completed(int((完成/长度)*100));
因为
done
和length
是int类型,而done IIRC Qt插槽是同步的。看,甚至更好的是正常的方式。。。完成上述连接后,fc->start();就是这样……您是否在FileCrypto
的构造函数中调用了moveToThread()
?应该有人更改问题陈述:)
#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()));
emit completed(100 * done / length);