使用 pypubsub & wxpython 在 Windows 之间传输数据获取 TypeError:

问题描述

我正在尝试使用 PyPubSub 在两个 wxpython 窗口之间传递数据。下面我将代码缩减为基础知识。当我在主窗口的 textcntrl 中填写数据并点击按钮将其传递到第二个窗口(CoordFrame)时我得到了什么我收到以下错误-

TypeError: sendMessage() 需要 2 个位置参数,但给出了 3 个

我能找到的每个例子都显示在 pub.sendMessage 中传递两个参数;这就是我认为我正在做的事情。传递的第三个参数是什么,它从哪里形成以及如何停止它?我尝试了各种参数组合和数据类型,包括二进制。

'''

from pubsub import pub
import wx

class MainFrame (wx.Frame):
    def __init__(self,parent,title):
        super(MainFrame,self).__init__(parent,title = title,size = (200,200))
        self.panel = MainPanel(self)

class CoordFrame (wx.Frame):
    def __init__(self,title):
        super(CoordFrame,200))
        self.panel = CoordPanel(self)


class MainPanel(wx.Panel):
    def __init__(self,parent):
        super(MainPanel,self).__init__(parent)
        vsizer = wx.BoxSizer(wx.VERTICAL)
    
        self.tbxNewMap = wx.TextCtrl(self,id=1001,pos=(20,20),size = (50,style = wx.TE_CENTER|wx.TE_NOHIDESEL|wx.TE_PROCESS_ENTER)
        vsizer.Add(self.tbxNewMap)

        self.btnEnterNewMap = wx.Button(self,id=1002,label = "New Data",pos = (20,80),size = (80,40))
        vsizer.Add(self.btnEnterNewMap,wx.EXPAND)
        self.Bind(wx.EVT_BUTTON,self.onButtonNewMap,id=1002)

    def onButtonNewMap(self,event):
        temp = self.tbxNewMap.GetValue()
        pub.sendMessage("coord_listener",temp)
        coordframe = CoordFrame(None,"Entry")
        coordframe.Show()

class CoordPanel(wx.Panel):
    def __init__(self,parent):
        super(CoordPanel,self).__init__(parent)
        vsizer = wx.BoxSizer(wx.VERTICAL)
        pub.subscribe(self.coord_listener,"coord_listener")

        self.tbxNewMapNumber = wx.TextCtrl(self,id=1000,style = wx.TE_CENTER|wx.TE_NOHIDESEL|wx.TE_PROCESS_ENTER)
        vsizer.Add(self.tbxNewMapNumber)
        
    def coord_listener(self,message):
        newmapnum = message
        self.tbxNewMapNumber.SetValue(newmapnum)
        self.tbxNewMapNumber.Refresh()


class GMDash(wx.App):
    def OnInit(self):
        self.mainframe = MainFrame(parent = None,title = "Dashboard")
        self.mainframe.Show()
        return True

app = GMDash()
app.MainLoop()

'''

解决方法

在对 sendmessage 的调用中使用命名参数,您需要注册发送消息的侦听器 before,而不是像您目前所做的那样。

见下文:

from pubsub import pub
import wx

class MainFrame (wx.Frame):
    def __init__(self,parent,title):
        super(MainFrame,self).__init__(parent,title = title,size = (200,200))
        self.panel = MainPanel(self)

class CoordFrame (wx.Frame):
    def __init__(self,title):
        super(CoordFrame,200))
        self.panel = CoordPanel(self)


class MainPanel(wx.Panel):
    def __init__(self,parent):
        super(MainPanel,self).__init__(parent)
        vsizer = wx.BoxSizer(wx.VERTICAL)
    
        self.tbxNewMap = wx.TextCtrl(self,id=1001,pos=(20,20),size = (50,style = wx.TE_CENTER|wx.TE_NOHIDESEL|wx.TE_PROCESS_ENTER)
        vsizer.Add(self.tbxNewMap)

        self.btnEnterNewMap = wx.Button(self,id=1002,label = "New Data",pos = (20,80),size = (80,40))
        vsizer.Add(self.btnEnterNewMap,wx.EXPAND)
        self.Bind(wx.EVT_BUTTON,self.onButtonNewMap,id=1002)
    #Register the subscrption *before* sending the message
        self.coordframe = CoordFrame(None,"Entry")

    def onButtonNewMap(self,event):
        temp = self.tbxNewMap.GetValue()
        pub.sendMessage("coord_listener",message=temp)
        #coordframe = CoordFrame(None,"Entry")
        self.coordframe.Show()

class CoordPanel(wx.Panel):
    def __init__(self,parent):
        super(CoordPanel,self).__init__(parent)
        vsizer = wx.BoxSizer(wx.VERTICAL)
        pub.subscribe(self.coord_listener,"coord_listener")

        self.tbxNewMapNumber = wx.TextCtrl(self,id=1000,style = wx.TE_CENTER|wx.TE_NOHIDESEL|wx.TE_PROCESS_ENTER)
        vsizer.Add(self.tbxNewMapNumber)
        
    def coord_listener(self,message):
        print(message)
        newmapnum = message
        self.tbxNewMapNumber.SetValue(newmapnum)
        self.tbxNewMapNumber.Refresh()


class GMDash(wx.App):
    def OnInit(self):
        self.mainframe = MainFrame(parent = None,title = "Dashboard")
        self.mainframe.Show()
        return True

app = GMDash()
app.MainLoop()

enter image description here