1 需求
2 接口
3 方案一:pubsub
main.py
from ui import ui
def main():
ui()
if __name__ == "__main__":
main()
ui.py
import wx
from pubsub import pub
from init import do_sth
class MyFrame(wx.Frame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.init_ui()
self.Center()
self.Maximize()
def init_ui(self):
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
btn = wx.Button(panel, label="开始扫描")
self.text_ctrl = wx.TextCtrl(panel, style=wx.TE_MULTILINE | wx.TE_READONLY)
sizer.Add(btn, 0, wx.ALL, 10)
sizer.Add(self.text_ctrl, 0, wx.ALL, 10)
panel.SetSizer(sizer)
btn.Bind(wx.EVT_BUTTON, self.btn_scan)
pub.subscribe(self.update_text, "xxxxxx")
def update_text(self, message):
self.text_ctrl.AppendText(message)
def btn_scan(self, event):
do_sth()
def ui():
app = wx.App()
frame = MyFrame(None, title="wxPython Demo")
frame.Show()
app.MainLoop()
if __name__ == "__main__":
ui()
init.py
from pubsub import pub
def do_sth():
pub.sendMessage("xxxxxx", message="hello")
4 参考资料
在 wxPython 中实现跨脚本使用 wx.TextCtrl
主要有两种方式:全局变量 和 对象引用传递。下面分别介绍这两种方法的实现。
方法一:使用全局变量(简单但耦合度高)
1. 创建主脚本 main.py
import wx
from another_script import update_text
class MyFrame(wx.Frame):
def __init__(self, parent, title):
super(MyFrame, self).__init__(parent, title=title, size=(400, 300))
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
# 创建 TextCtrl 并设为全局变量
global my_text_ctrl
my_text_ctrl = wx.TextCtrl(panel, style=wx.TE_MULTILINE)
sizer.Add(my_text_ctrl, 1, wx.EXPAND | wx.ALL, 10)
# 创建按钮,点击后调用另一个脚本中的函数
btn = wx.Button(panel, label="更新文本")
btn.Bind(wx.EVT_BUTTON, self.on_update)
sizer.Add(btn, 0, wx.ALIGN_CENTER | wx.ALL, 10)
panel.SetSizer(sizer)
self.Show()
def on_update(self, event):
# 调用另一个脚本中的函数更新文本
update_text("来自另一个脚本的文本")
if __name__ == '__main__':
app = wx.App()
frame = MyFrame(None, "跨脚本使用 TextCtrl")
app.MainLoop()
2. 创建辅助脚本 another_script.py
def update_text(new_text):
# 直接访问全局变量 my_text_ctrl
import main
main.my_text_ctrl.SetValue(new_text)
方法二:通过对象引用传递(推荐,低耦合)
1. 创建主脚本 main.py
import wx
from another_script import TextUpdater
class MyFrame(wx.Frame):
def __init__(self, parent, title):
super(MyFrame, self).__init__(parent, title=title, size=(400, 300))
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
self.my_text_ctrl = wx.TextCtrl(panel, style=wx.TE_MULTILINE)
sizer.Add(self.my_text_ctrl, 1, wx.EXPAND | wx.ALL, 10)
btn = wx.Button(panel, label="更新文本")
btn.Bind(wx.EVT_BUTTON, self.on_update)
sizer.Add(btn, 0, wx.ALIGN_CENTER | wx.ALL, 10)
panel.SetSizer(sizer)
self.Show()
# 创建辅助类实例并传入 TextCtrl 引用
self.updater = TextUpdater(self.my_text_ctrl)
def on_update(self, event):
# 通过辅助类更新文本
self.updater.update("来自另一个脚本的文本")
if __name__ == '__main__':
app = wx.App()
frame = MyFrame(None, "跨脚本使用 TextCtrl")
app.MainLoop()
2. 创建辅助脚本 another_script.py
class TextUpdater:
def __init__(self, text_ctrl):
# 保存 TextCtrl 引用
self.text_ctrl = text_ctrl
def update(self, new_text):
# 使用保存的引用更新文本
self.text_ctrl.SetValue(new_text)
方法三:使用自定义事件(更灵活,适合复杂场景)
1. 创建主脚本 main.py
import wx
from another_script import send_update_request
# 定义自定义事件
UPDATE_TEXT_EVENT = wx.NewEventType()
EVT_UPDATE_TEXT = wx.PyEventBinder(UPDATE_TEXT_EVENT, 1)
class UpdateTextEvent(wx.PyCommandEvent):
def __init__(self, etype, eid, value=None):
wx.PyCommandEvent.__init__(self, etype, eid)
self._value = value
def GetValue(self):
return self._value
class MyFrame(wx.Frame):
def __init__(self, parent, title):
super(MyFrame, self).__init__(parent, title=title, size=(400, 300))
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
self.my_text_ctrl = wx.TextCtrl(panel, style=wx.TE_MULTILINE)
sizer.Add(self.my_text_ctrl, 1, wx.EXPAND | wx.ALL, 10)
btn = wx.Button(panel, label="更新文本")
btn.Bind(wx.EVT_BUTTON, self.on_update)
sizer.Add(btn, 0, wx.ALIGN_CENTER | wx.ALL, 10)
panel.SetSizer(sizer)
self.Show()
# 绑定自定义事件
self.Bind(EVT_UPDATE_TEXT, self.on_text_update)
def on_update(self, event):
# 调用另一个脚本中的函数发送事件请求
send_update_request(self.GetId(), "来自另一个脚本的文本")
def on_text_update(self, event):
# 处理事件,更新文本
self.my_text_ctrl.SetValue(event.GetValue())
if __name__ == '__main__':
app = wx.App()
frame = MyFrame(None, "跨脚本使用 TextCtrl")
app.MainLoop()
2. 创建辅助脚本 another_script.py
import wx
def send_update_request(window_id, text):
# 发送自定义事件到主窗口
from main import UPDATE_TEXT_EVENT
event = wx.PyCommandEvent(UPDATE_TEXT_EVENT, window_id)
event.SetString(text)
wx.PostEvent(wx.FindWindowById(window_id), event)
推荐方案选择
- 简单场景:使用方法一(全局变量),实现简单但耦合度高。
- 中等复杂度:使用方法二(对象引用传递),推荐方式,低耦合且易于维护。
- 复杂交互:使用方法三(自定义事件),适合多模块间的灵活通信。