Рубрики
Без рубрики

wxpython и pubsub: простое руководство

Получите практические, реальные навыки Python на наших ресурсах и пути

Автор оригинала: Mike Driscoll.

Я вижу ряд вопросов по списку рассылки WXPYPHON или его канал IRC об общении между кадрами и большую часть времени, что потребности разработчика является модулем Pubsub. Модель издателя/подписчика – это способ отправлять сообщения одному или нескольким слушателям. Вы можете прочитать об этом здесь Отказ Узор наблюдателя Говорят, что основано на моделей публикации/подписке. В земле WXPYPHON у нас есть модуль PUBSUB, который может быть доступен из wx.lib.pubsub. Он на самом деле включен в wxpython, но вы также можете скачать его как автономный модуль из его Source Forge Отказ Альтернатива Pubsub это Pydispatcher модуль.

Во всяком случае, в этой статье мы не будем изучать теорию позади любой из этих модулей. Вместо этого мы будем использовать полупрепаративный пример в WXPYPHON, чтобы показать, как использовать встроенную версию PUBSUB для связи между двумя кадрами. Если вы все еще со мной в этот момент, то я призываю вас читать! Обновление: эта статья для wxpython 2.8. Если вы будете использовать более новую версию WxPython, то вы захотите прочитать мою новую версию этой статьи здесь

Как пройти информацию между двумя кадрами

Я обнаружил, что иногда мне нужно открыть немодальную рамку, чтобы получить информацию от пользователя, а затем передавать эту информацию обратно к основным кадрам моей приложения. В других случаях мне нужно просто сказать одно из моих кадров, что другой закрыл. В этих двух случаях Pubsub приходит к спасению. В следующем примере фактически продемонстрировано решение об обоих этих вопросах.

import wx
from wx.lib.pubsub import Publisher

########################################################################
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="")
        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(closeBtn, 0, flags, 5)
        panel.SetSizer(sizer)
        
    #----------------------------------------------------------------------
    def onSendAndClose(self, event):
        """
        Send a message and close frame
        """
        msg = self.msgTxt.GetValue()
        Publisher().sendMessage(("show.mainframe"), msg)
        self.Close()
    

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

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent=parent)
        self.frame = parent
        
        Publisher().subscribe(self.showFrame, ("show.mainframe"))
        
        self.pubsubText = wx.TextCtrl(self, value="")
        hideBtn = wx.Button(self, label="Hide")
        hideBtn.Bind(wx.EVT_BUTTON, self.hideFrame)
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.pubsubText, 0, wx.ALL|wx.CENTER, 5)
        sizer.Add(hideBtn, 0, wx.ALL|wx.CENTER, 5)
        self.SetSizer(sizer)
        
    #----------------------------------------------------------------------
    def hideFrame(self, event):
        """"""
        self.frame.Hide()
        new_frame = OtherFrame()
        new_frame.Show()
        
    #----------------------------------------------------------------------
    def showFrame(self, msg):
        """
        Shows the frame and shows the message sent in the
        text control
        """
        self.pubsubText.SetValue(msg.data)
        frame = self.GetParent()
        frame.Show()
        
########################################################################
class MainFrame(wx.Frame):
 
    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Pubsub Tutorial")
        panel = MainPanel(self)
        
        
#----------------------------------------------------------------------
if __name__ == "__main__":
    app = wx.App(False)
    frame = MainFrame()
    frame.Show()
    app.MainLoop()

Наша первая остановка в туре по настоящему Кодексу находится в классе Mainpanel. Примите к сведению следующую строку:

Publisher().subscribe(self.showFrame, ("show.mainframe"))

Это создает слушатель Singleton (AKA: приемник), который подписывается на тему «Show.Mainframe». Другие части программы могут публиковать на эту тему, и слушатель заберет их и позвонит в метод «ShowFrame». Чтобы увидеть это в действии, ознакомьтесь с методом «Onsendloselose» «Onsendloselose» «OnsendClose Onframe».

# OtherFrame Class
def onSendAndClose(self, event):
    """
    Send a message and close frame
    """
    msg = self.msgTxt.GetValue()
    Publisher().sendMessage(("show.mainframe"), msg)
    self.Close()

Здесь мы получаем значение управления текстовым управлением, чтобы отправить обратно в наш основной кадр. Чтобы отправить его, мы называем Издательство Объект SendMessage Способ и пройти тему строку и сообщение. Сообщение может быть список объектов или только один объект. В этом случае это просто строка. Вернуться в Mainpanel , ShowFrame Метод вызывается. Вот что это выглядит:

# MainPanel class
def showFrame(self, msg):
    """
    Shows the frame and shows the message sent in the
    text control
    """
    self.pubsubText.SetValue(msg.data)
    frame = self.GetParent()
    frame.Show()

В этом методе мы извлекаем данные, отправленные через Pubsub через его данные имущество. Если бы мы отправили несколько элементов, используя список, нам нужно было сделать что-то вроде msg.data [0], чтобы получить на правильном элементе (при условии, что строка была в элементе элемента). Новейший Pubsub имеет немного другой API, который вы можете проверить в своем Кулинарная книга Отказ Новейшая API доступна как WxPython 2.8.11.0. ПРИМЕЧАНИЕ. У меня были проблемы с созданием бинара с новейшим Pubsub, потому что я использовал немного более старые API. Смотрите это нить Для деталей и для некоторых возможных обходных путей.

Теперь вы знаете основы использования Pubsub в вашем проекте. Этот пример показывает, как общаться между двумя кадрами, даже если кто-то скрыт! Он также показывает, как передавать информацию от одного кадра к другому. Повеселись!

Дополнительное чтение