如何在 PyQt 中使用 QThreads 和 libtorrent?

Posted

技术标签:

【中文标题】如何在 PyQt 中使用 QThreads 和 libtorrent?【英文标题】:How to use QThreads with libtorrent in PyQt? 【发布时间】:2013-05-21 21:21:52 【问题描述】:

我想编写一些简单的 PyQt 洪流客户端,但我遇到了一些问题。 我想运行一些循环来处理在 PyQt 代码中下载文件(使用 libtorrent 的简单代码)。 虽然,当洪流下载工作时,用户界面不显示,当我更改调用函数的顺序时,用户界面显示但下载不工作。 我读过关于 QThreads 的文章,但对我来说有点难——谁能解释 QThread 是如何工作的以及如何将它与 libtorrent 一起使用? 下面是一些 torrent 客户端代码示例:

import libtorrent as lt
import time
import sys

ses = lt.session()
ses.listen_on(6881, 6891)

info = lt.torrent_info(sys.argv[1])
h = ses.add_torrent('ti': info, 'save_path': './')
print 'starting', h.name()

while (not h.is_seed()):
   s = h.status()

   state_str = ['queued', 'checking', 'downloading metadata', \
      'downloading', 'finished', 'seeding', 'allocating', 'checking fastresume']
   print '\r%.2f%% complete (down: %.1f kb/s up: %.1f kB/s peers: %d) %s' % \
      (s.progress * 100, s.download_rate / 1000, s.upload_rate / 1000, \
      s.num_peers, state_str[s.state]),
   sys.stdout.flush()

   time.sleep(1)

print h.name(), 'complete'

【问题讨论】:

【参考方案1】:

我想 QT 会运行一个消息循环,直到应用程序终止才会返回。

我相信您想要做的是将循环体(轮询 libtorrent 状态)移动到 QT 定期调用的消息处理程序中。比如说一个定时器功能。

【讨论】:

【参考方案2】:

首先我会推荐 Qt 的 PySide 实现。

在那种情况下(和普通的 pyQt)你应该研究信号和槽:

http://qt-project.org/wiki/Signals_and_Slots_in_PySide

http://zetcode.com/gui/pyqt4/eventsandsignals/

基本上,您只需要设置通常称为“Worker”的类,它只是一个 QThread。

class Worker(QtCore.QThread):
    updateProgress = QtCore.Signal(int) #or whatever you wanna call it 

这 ^^^ 是上面的代码所在的位置。 然后你要做的是在主 GUI 线程/类中连接信号。

self.worker.updateProgress.connect(self.setProgress) #notice no ()


def setProgress(self, progress):
    self.progressBar.setValue(progress) 

最后在函数内部输出你想要的值:

self.updateProgress.emit(value)

这个例子暗示了类似进度条的功能。我知道这篇文章已经过时了——但这会对我有所帮助,所以希望谷歌员工会发现它很有用;)

【讨论】:

以上是关于如何在 PyQt 中使用 QThreads 和 libtorrent?的主要内容,如果未能解决你的问题,请参考以下文章

如何确保 QApplication 及其 QThreads 全部关闭

一起使用 psycopg2 和 Qthreads(或者只是 postgresql 和 qthreads)并更新 GUI

为啥我的 QThreads 总是让 Maya 崩溃?

带参数传递的 QThreads

与 QThreads 通信

在 QDialog::exec() 期间使用 QThreads 执行 QWidget::grab()