• 7275阅读
  • 3回复

请教个QProgressDialog 不更新进度条的问题 [复制链接]

上一主题 下一主题
 
只看楼主 正序阅读 楼主  发表于: 2009-03-09
一下午一直在搞这个进度条的问题,弄的我实在是很头大.

现在已经最好结果下,不出任何问题的让一个几百兆的东西传输完毕,进度条"数字",也显示完毕.但是进度条的那个条,永远不动,永远没有颜色.

问题有这些:

1.我的数据包是,一次传输2K的数据包.这个问题其实我也不明白为什么不能搞大一点,因为之前我用的是1001 B的数据包来传输文件的.没有任何问题,但是就是慢,本机传输只有300多K每秒.

然后我改成20K的大小,问题多的要命,就是接收包似乎一次接收不完,所以包头就被破坏了,因为客户端是根据包头信息来判断是文件结束还是其他什么的.

我当时用的方法是:

while (socket->bytesAvailable() > 0 )
{
    readsize += a->socket->read(&buff[readsize],2001);
}

这样来循环读那20K的包,直到读完为止. 然后对这个BUFF进行操作,判断buff[0] 也就是包头,然后写入文件什么的.
这个缓冲包是类的成员变量,不是临时变量. 每次先清空,再读SOCKET

问题就是,最多读几个20K的数据包,很少的几个,立即弹出未定义包头的错误,这个错误弹出框是我写的,证明包头是未识别的. 而且从这个错误的包的内容来看(每次会显示该包内容).

这20K的包被分割了,没有把20K的包读完,但是 bytesAvailable() 已经为 0,所以会跳出循环,导致后面的全盘错误.

但是如果我的循环条件是 以是否读满20K为准,问题就出在文件结束,文件最后那一次一定没有20K,所以到最后服务器端一定发不到20K的包,客户端也就接收不到20K,也就会死循环了.

最后实在没办法,我把数据包改成2001 B,就再没问题,但是我却不敢保证网络不好的情况下会不会依然读不完,造成上面的问题. 2001 B 的数据包,本机传输速度将近1MB了.

而进度条是每传送一次2001 B的包, 更新一次进度, 用的是接收到的文件大小 / 文件总大小 为参数 调用  progress->setValue()

问题就来了,传一个100MB的东西,进度条到10%多,就卡住了,包括网络也卡住了,但是程序并没有无响应.  原因也不知道,我猜是因为调用函数太多导致的吧?


2.上面的问题我用另外的方法解决了,就是用时间信号,每2秒一个TIMEOUT信号触发一个槽函数,这个槽函数开始一个2秒的计时器,并且更新进度条,所以这就是一个2秒一次更新进度条的循环了.

网络不再卡住,卡住的依然是进度条,进度条卡在10-20%左右,不动. 这个TIMEOUT触发的槽函数执行只有2句.
    this->progress->setValue(size * 100 / maxsize);
    this->timer->start(2000);

为什么会这样?不知道,后来我解决了,问题出在那个算式上.不能每次带一个算式进去.而要这样,构造这个progress 的时候,范围是 0 - maxsize ,然后每次更新进度条的参数,是size,这样,就完美的显示完成
不会卡住. WHY?

3.也就是最终没解决的问题,颜色条,只会动2-3次,30%多的时候,突然画了一次,但是画的长度不像30%多,像40%多,第二次,在70%多,画了一次颜色条,但是,这次的整个进度条中间还有个分段的线.
而且长度差不多是90%的进度条长度.

这个问题到现在也不知道为什么.前面几个问题的原因也不知道.

还望各位高手能给我解答一下,万分感谢.


只看该作者 3楼 发表于: 2009-03-10
不出错了,只不过我是传的2000 B
如果要速度快,修改的地方挺多的,要改包.

因为如果一次传20K那么大的话,我就必须等 bytesAvailable 的大小=20K 我才进行操作.
但是很明显文件传输的最后一次,文件肯定剩下不到20K,那这个判断就会造成最后一步传输不完.
唯一的办法就是,每次readReady 信号来了后,槽函数 对 包前6个字节进行识别,里面放的是该包的大小,这样就让 bytesAvailable 可变了.
但是改的地方就挺多的,服务器端发送的包也要改.

但是到目前为止,问题只有2个需要解决的
1.进度条不动,数字动.

2.  我还有个修改文件名的功能有问题:
    QFile  file;
    file.setFileName(QString(oldname));
    file.exists()  是返回true 的.
  
    file.rename(QString(oldname),QString(newname))  服务器端永远是返回失败,无法修改文件名.
    file.renmae(QString(newname))     服务器端永远是直接把文件给我删了.返回成功
    oldname 和 newname  我都在服务器端显示出来了的,没有错.

难道rename 有其他什么隐含作用?
望指教,谢谢.
只看该作者 2楼 发表于: 2009-03-10
哟,lz的传输不出错了啊
只看该作者 1楼 发表于: 2009-03-10
都没有人知道吗?
快速回复
限100 字节
 
上一个 下一个