Python-难点-跨脚本使用wx.TextCtrl

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)

推荐方案选择

  • 简单场景:使用方法一(全局变量),实现简单但耦合度高。
  • 中等复杂度:使用方法二(对象引用传递),推荐方式,低耦合且易于维护。
  • 复杂交互:使用方法三(自定义事件),适合多模块间的灵活通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值