所以我用QNetworkAccessManager(当然还有NetworkReply和Request)来下载。当它完全没有线程化的时候,我可以让它工作得非常好——并且阻塞了应用程序,但是不管我试图用什么方法让它以非阻塞的方式运行,它都不起作用。在
NetworkAccessManager中的.get()似乎被调用,但要么从不连接,要么从不发送信号进行任何写入。在
如果你想知道为什么代码的某些部分是这样设置的,那是为了更容易地改变来尝试一堆不同的方法。在
我读到的一件事就是试着用QtCore.QTimer.singleShot(0,CALL)在某些信号发出时将控制权发送回主事件循环-我尝试了此操作,但没有成功。在
from PyQt4 import QtNetwork, QtCore, QtGui
import sys
import os
class Downloader(QtNetwork.QNetworkAccessManager):
def __init__(self, url, dest):
super(Downloader, self).__init__(None)
self.get_path = url
self.url = QtCore.QUrl(url)
self.download_buffer = QtCore.QByteArray()
self.dest = self.set_up_destination(dest)
# self.request = QtNetwork.QNetworkRequest(self.url)
# self.reply = self.get(self.request)
#
# self.reply.readyRead.connect(self.read_data)
self.finished.connect(self.write_finished)
print 'Downloader Inited'
def startDownload(self):
self.request = QtNetwork.QNetworkRequest(self.url)
self.reply = self.get(self.request)
self.reply.readyRead.connect(self.read_data)
def set_up_destination(self, dest):
if '.' in dest:
dir_dest = os.path.dirname(dest)
if not os.path.isdir(dir_dest):
os.makedirs(dir_dest)
return dest
else:
if not os.path.isdir(dest):
os.makedirs(dest)
base = os.path.basename(self.get_path)
return os.path.join(dest, base).replace('\\', '/')
def write_finished(self):
write_file = QtCore.QFile(self.dest)
if write_file.open(QtCore.QIODevice.WriteOnly):
write_file.write(self.download_buffer)
write_file.close()
print 'Wrote File: {0}'.format(os.path.basename(self.dest))
else:
print 'ERROR'
def read_data(self):
self.download_buffer += self.reply.readAll()
def print_progress(self, gotten, total):
gotten = gotten/float(1000000)
total = total/float(1000000)
self.total = total
divisor = total/5.0
if gotten > (divisor*self.notify_count):
self.notify_count += 1
print 'Downloaded {0}/{1} Mb'.format(gotten, total)
else:
pass
class DownloadForm(QtGui.QDialog):
def __init__(self, from_dir, to_dir):
super(DownloadForm, self).__init__(None)
self.from_dir = from_dir
self.to_dir = to_dir
self.downloaders = []
self.run_count = 0
self.done_count = 0
self.display_label = QtGui.QLabel('Downloading items...')
self.vlayout = QtGui.QVBoxLayout()
self.vlayout.addWidget(self.display_label)
self.setLayout(self.vlayout)
self.start_downloads(self.from_dir, self.to_dir)
def start_downloads(self, from_dir, to_dir):
items = os.path.listdir(from_dir)
items = [os.path.join(from_dir, x) for x in items]
self.run_count = len(items)
self.display_label.setText('Downloading {0} items...'.format(self.run_count))
for item in items:
print 'starting item: {0}'.format(os.path.basename(from_dir))
m = Downloader(item, to_dir)
m.finished.connect(self.adjust_run_count)
self.downloaders.append(m)
for item in self.downloaders:
item.startDownload()
@QtCore.pyqtSlot(object)
def adjust_run_count(self, v):
self.done_count += 1
if self.done_count >= self.run_count:
self.display_label.setText('All Items Finished!')
class Thread(QtCore.QThread):
def __init__(self, lst):
super(Thread, self).__init__(None)
self.lst = lst
def run(self):
for item in self.lst:
item.startDownload()
if __name__ == '__main__':
app = QtGui.QApplication([])
DIR1 = None #Give it a path to a folder containing some files
DIR2 = None #Give it a path to an empty folder to 'copy' to.
form = DownloadForm('DIR1',
'DIR2')
form.show()
app.exec_()
它的设置是在本地运行,现在只是为了让它工作。在
这是我最近的一次尝试(我觉得没用,但前几天我在某个地方看到了类似的帖子,所以我想在来这里之前我已经用尽了所有的资源——这一次真的很糟糕!!!)在
我尝试过一些事情,比如: 创建了一个线程(作为GUI的一个子线程),它实际创建了每个Manager对象,存储了一个var,关于它所生成的管理器(例如,50)将它们的finish signal连接到它自己的插槽,这个插槽将增加一个“finished”的var,直到它达到50(表示它们都完成了),然后它将发出自己的信号,或者打印“done”或其他东西。在
以微笑的信号/插槽方式为每个作业创建单独的线程
你们都明白了,我还尝试了其他几种方法——它们都有共同点: -涉及的QThreads -要么A)不工作,要么B(更有可能)工作,我做错了。在
我有点不知所措。 希望有人能帮忙!在
目前没有回答
相关问题 更多 >
编程相关推荐