我正在开发我的宠物项目。这是一个从 Facebook 下载我的收件箱文件夹的小应用程序。我希望它在 CLI 和 GUI(在 PyQt 中)模式下都可用。我的想法是先写一个交流类,然后是前端。我知道下载过程被阻塞,这在 CLI 模式下不是问题,但它在 GUI 中。我知道有,QNetworkAccessManager
但我必须重新实现我已经编写的类,然后同时维护两个类。
我搜索了一段时间,我想出了一个解决方案,我将子类QObject
和我的FB
类,实现信号,而不是创建一个QThread
对象并使用可以的moveToThread()
方法,但我必须注意创建和停止胎面。
是否可以将我的 Python 类包装成某种东西以使其表现得像QNetworkAccessManager
?所以方法会立即返回,并且当数据准备好时对象会发出信号。
更新
谢谢你的意见。我有2个主要课程。第一个被称为SimpleGraph
只是隐藏urllib2.urlopen()
。它准备查询并返回从 Facebook 获取的解码 json。实际工作发生在FBMDown
课堂上:
class FBMDown(object):
def __init__(self, token):
self.graph = SimpleGraph(token)
self.last_msg_count = 0
def _message_count(self, thread_id):
#TODO: Sanitize thread_id
p = {'q': 'SELECT message_count FROM thread WHERE thread_id = {0} LIMIT 1'.format(thread_id)}
self.last_msg_count = int(self.graph.call(params=p, path='fql')['data'][0]['message_count'])
return self.last_msg_count
因此,当_message_count
被调用时,它返回给定线程 id 的消息数。此方法在 CLI 模式下效果很好,在那里阻塞不是问题。我想将这个类包装成一个类(如果可能的话),它像异步一样工作QNetworkAccessManager
,所以它不会阻塞 GUI,但它会在数据准备好时发出信号。我现在知道的唯一技术是子类化QObject
. 它看起来像这样:
class QFBMDown(QtCore.QObject):
msg_count_signal = QtCore.pyqtSignal(int)
def __init__(self, parent=None):
QtCore.QObject.__init__(self, parent)
def get_msg_count(self):
#Here happens the IO
time.sleep(2)
self.msg_count_signal.emit(1)
这是我的 Windows 课程:
class Window(QtGui.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.centralwidget = QtGui.QWidget(self)
self.button_getmsgcount = QtGui.QPushButton(self.centralwidget)
self.setCentralWidget(self.centralwidget)
self.i = 0
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.block_indicator)
self.timer.start(20)
#self.worker = QtCore.QThread()
self.fbobj = QFBMDown()
#self.fbobj.moveToThread(self.worker)
#self.worker.start()
self.button_getmsgcount.clicked.connect(self.fbobj.get_msg_count)
self.fbobj.msg_count_signal.connect(self.show_msg_count)
def block_indicator(self):
self.button_getmsgcount.setText(str(self.i))
self.i += 1
def show_msg_count(self, data):
print 'Got {0} msgs in the thread'.format(data)
现在,当我按下按钮时,GUI 会阻塞。如果我取消注释第 13、15、16 行(我在其中创建一个线程,移入fbobj
该线程然后启动它)它不会阻塞,它几乎可以按我的意愿工作,但我每次都必须手动完成所有操作,我有照顾关闭线程(现在我实现了在退出前关闭线程QMainWindow
的 closeEvent
方法,但我确信这不是正确的方法)。
我想做什么甚至可能吗?我不想实现一个新类,然后维护两个做同样事情的类。我坚持这样做的原因是为了让我的应用程序在没有 Qt 的情况下工作,但为那些不想键入命令行参数的人提供一个很好的 gui。