0

我正在开发我的宠物项目。这是一个从 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该线程然后启动它)它不会阻塞,它几乎可以按我的意愿工作,但我每次都必须手动完成所有操作,我有照顾关闭线程(现在我实现了在退出前关闭线程QMainWindowcloseEvent方法,但我确信这不是正确的方法)。

我想做什么甚至可能吗?我不想实现一个新类,然后维护两个做同样事情的类。我坚持这样做的原因是为了让我的应用程序在没有 Qt 的情况下工作,但为那些不想键入命令行参数的人提供一个很好的 gui。

4

0 回答 0