python pubsub订阅了多个主题

时间:2014-03-17 14:08:45

标签: python wxpython publish-subscribe subscription

这看起来有点普遍,但实际上问题很简单。是否可以使用pubsub模块订阅主题的子集。

让我简要解释一下我想要完成的事情。在wxpython项目中,我想根据不同的事件更改状态栏中的文本。所以我想有一个函数(一个监听器)可以订阅一组主题。在监听器中,我将使用if语句和几个elif语句来检查主题的名称。然后状态栏文本将相应更改。

是否可以这样做,或者首先是一个坏主意。我应该如何处理这种情况。 提前致谢

3 个答案:

答案 0 :(得分:1)

首先,这是一个坏主意。您应该让pubsub为您完成工作。每个主题一个听众。这样做没有任何成本,它会隔离您的代码,使维护更容易,责任分离。

也就是说,一个监听器可以监听基本主题:pub.subscribe('a.b', listener)将获取主题ab,abc,abd,abce等的消息。如pubsub文档中所述,你可以告诉pusub给出主题对象通过使用默认值为pub.AUTO_TOPIC的关键字arg作为邮件的一部分。但是如果你使用这个策略并且最终得到一个if / elif / else的长列表,那么它可能就不可能了。

也许如果您提供有关您打算拥有的主题层次结构的更多详细信息,以及您想到的if / else的类型,我可以提供更有用的反馈。

答案 1 :(得分:0)

有几种方法。首先,也许最简单,你可以只有一个听众。当您发布到侦听器时,您只需传递不同的信息。例如,从A类开始,您将传递一个字符串。对于B类,您可以传递不同的字符串,但是传递给同一个侦听器。然后在监听器中,您只需检查您提到的字符串。

另一种方法是创建多个绑定到同一函数或方法的侦听器。然后你可以发布到不同的听众,他们都会调用相同的东西。

您应该使用最容易理解和调试的方法。

以下是一个例子:

import wx
from wx.lib.pubsub import pub 

########################################################################
class OtherFrame(wx.Frame):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, wx.ID_ANY, "Secondary Frame")
        panel = wx.Panel(self)

        msg = "Enter a Message to send to the main frame"
        instructions = wx.StaticText(panel, label=msg)
        self.msgTxt = wx.TextCtrl(panel, value="")

        sendBtn = wx.Button(panel, label="Send Msg")
        sendBtn.Bind(wx.EVT_BUTTON, self.onSendMsg)

        closeBtn = wx.Button(panel, label="Send and Close")
        closeBtn.Bind(wx.EVT_BUTTON, self.onSendAndClose)

        sizer = wx.BoxSizer(wx.VERTICAL)
        flags = wx.ALL|wx.CENTER
        sizer.Add(instructions, 0, flags, 5)
        sizer.Add(self.msgTxt, 0, flags, 5)
        sizer.Add(sendBtn, 0, flags, 5)
        sizer.Add(closeBtn, 0, flags, 5)
        panel.SetSizer(sizer)

    #----------------------------------------------------------------------
    def onSendMsg(self, event):
        """"""
        msg = "Another message!"
        pub.sendMessage("anotherListener", 
                        message=msg,
                        listener="anotherListener")

    #----------------------------------------------------------------------
    def onSendAndClose(self, event):
        """
        Send a message and close frame
        """
        msg = self.msgTxt.GetValue()
        pub.sendMessage("panelListener", 
                        message=msg,
                        listener="panelListener")
        self.Close()

########################################################################
class MyPanel(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)
        pub.subscribe(self.myListener, "panelListener")
        pub.subscribe(self.myListener, "anotherListener")

        btn = wx.Button(self, label="Open Frame")
        btn.Bind(wx.EVT_BUTTON, self.onOpenFrame)

    #----------------------------------------------------------------------
    def myListener(self, message, listener=None):
        """
        Listener function
        """

        if listener == "panelListener":
            print "panel listener has sent the following: ",
            print message
        elif listener == "anotherListener":
            print "another listener sent the following: ", 
            print message

    #----------------------------------------------------------------------
    def onOpenFrame(self, event):
        """
        Opens secondary frame
        """
        frame = OtherFrame()
        frame.Show()

########################################################################
class MyFrame(wx.Frame):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="New PubSub API Tutorial")
        panel = MyPanel(self)
        self.Show()

#----------------------------------------------------------------------
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()

这是我教程中的修改示例:http://www.blog.pythonlibrary.org/2013/09/05/wxpython-2-9-and-the-newer-pubsub-api-a-simple-tutorial/

答案 2 :(得分:0)

另一种方法是多次调用 pub.subscribe ,用于相同的订阅者功能但具有不同的特定子主题。例如,假设您有一个垃圾邮件过滤器,可将垃圾邮件分为20个不同的特定类别,这些类别可分为五组。此时您只想处理这两类的两组。这是一种方式:

def delete_spam_subscriber(header, message):
   delete_message(header, message)

def junkmail_subscriber(header, message):
   move_to_junk(header, message)

pub.subscribe(delete_spam_subscriber, 'root.spam.profanity')
pub.subscribe(delete_spam_subscriber, 'root.spam.spyware')
pub.subscribe(delete_spam_subscriber, 'root.spam.indirect')

pub.subscribe(junkmail_subscriber, 'root.spam.unknown_sender')
pub.subscribe(junkmail_subscriber, 'root.spam.forum_replys')
pub.subscribe(junkmail_subscriber, 'root.spam.receive_but_limit')

当然,如果您不想通过对主题“root.spam.deletables”,“root.spam.to_junk_folder”进行分组来创建