wxpython设计GUI:不同的滑块控件共用同一个响应事件函数

本文档记录了一位开发者在wxPython中优化滑块事件处理的过程。原有的代码为每个滑块控件绑定了单独的事件处理函数,导致大量重复代码。通过尝试,最终成功地将事件处理函数统一,但实现方式仍需手动为每个滑块设置事件,未能完全自动化。代码修改后,当滑块数量改变时,仍需手动调整事件绑定。
摘要由CSDN通过智能技术生成

背景:10个输入对象,每个对象对应一个滑块slider控件和文本框textctrl控件,用户拉动对应输入对象的滑块后,滑块的数值会显示在滑块控件下方的文本框内,这10个滑块的响应事件函数本质是功能是一样的,只是对应输入的滑块控件名称和文本框控件名称不同。现在期望实现的功能是避免重复定义相似功能的函数,当输入对象的个数变化不是10个时,滑块的响应事件执行函数能够根据输入对象个数相应的获取对应的滑块slider控件和文本框textctrl控件。

原程序代码:

 # 拉动滑块事件
        self.m_slider1.Bind(wx.EVT_SCROLL, self.get_item1_value)
        self.m_slider2.Bind(wx.EVT_SCROLL, self.get_item2_value)
        self.m_slider3.Bind(wx.EVT_SCROLL, self.get_item3_value)
        self.m_slider4.Bind(wx.EVT_SCROLL, self.get_item4_value)
        self.m_slider5.Bind(wx.EVT_SCROLL, self.get_item5_value)
        self.m_slider6.Bind(wx.EVT_SCROLL, self.get_item6_value)
        self.m_slider7.Bind(wx.EVT_SCROLL, self.get_item7_value)
        self.m_slider8.Bind(wx.EVT_SCROLL, self.get_item8_value)
        self.m_slider9.Bind(wx.EVT_SCROLL, self.get_item9_value)
        self.m_slider10.Bind(wx.EVT_SCROLL, self.get_item10_value)
        
    def get_item1_value(self, event):
        item_value = self.m_slider1.GetValue()  # 返回int
        self.m_textCtrl2.SetValue(str(item_value))

    def get_item2_value(self, event):
        item_value = self.m_slider2.GetValue()  # 返回int
        self.m_textCtrl3.SetValue(str(item_value))

    def get_item3_value(self, event):
        item_value = self.m_slider3.GetValue()  # 返回int
        self.m_textCtrl4.SetValue(str(item_value))

    def get_item4_value(self, event):
        item_value = self.m_slider4.GetValue()  # 返回int
        self.m_textCtrl5.SetValue(str(item_value))

    def get_item5_value(self, event):
        item_value = self.m_slider5.GetValue()  # 返回int
        self.m_textCtrl6.SetValue(str(item_value))

    def get_item6_value(self, event):
        item_value = self.m_slider6.GetValue()  # 返回int
        self.m_textCtrl7.SetValue(str(item_value))

    def get_item7_value(self, event):
        item_value = self.m_slider7.GetValue()  # 返回int
        self.m_textCtrl8.SetValue(str(item_value))

    def get_item8_value(self, event):
        item_value = self.m_slider8.GetValue()  # 返回int
        self.m_textCtrl9.SetValue(str(item_value))

    def get_item9_value(self, event):
        item_value = self.m_slider9.GetValue()  # 返回int
        self.m_textCtrl10.SetValue(str(item_value))

    def get_item10_value(self, event):
        item_value = self.m_slider10.GetValue()  # 返回int
        self.m_textCtrl11.SetValue(str(item_value))

解决办法:可以将参数传递给事件处理程序,可以使用lambda: …来完成。

第一次尝试修改:

        # 拉动滑块事件
        for i in range(len(item_list)):
            param = [self.set_slider_dict(i), self.set_itemtextctrl_dict(i)]
            self.set_slider_dict(i).Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param))
            
    def set_slider_dict(self, idx):
        slider_list = [self.m_slider1, self.m_slider2, self.m_slider3, self.m_slider4, self.m_slider5,
                       self.m_slider6, self.m_slider7, self.m_slider8, self.m_slider9, self.m_slider10]
        slider_dict = {}
        for i in range(len(item_list)):
            slider_dict[i] = slider_list[i]
        return slider_dict[idx]

    def set_itemtextctrl_dict(self, idx):
        textctrl_list = [self.m_textCtrl2, self.m_textCtrl3, self.m_textCtrl4, self.m_textCtrl5,
                         self.m_textCtrl6, self.m_textCtrl7, self.m_textCtrl8, self.m_textCtrl9,
                         self.m_textCtrl10, self.m_textCtrl11]
        textctrl_dict = {}
        for i in range(len(item_list)):
            textctrl_dict[i] = textctrl_list[i]
        return textctrl_dict[idx]
        
    def get_item_value(self, event, param):
        item_value = param[0].GetValue()  # 返回int
        print("item_value", item_value)
        param[1].SetValue(str(item_value))

修改无效,10个滑块同时响应的是最后一个滑块的滑块拉动数值。得到的结论是不能采用for循环的方式为每一个滑块定义相同的触发事件函数。

第二次尝试修改:

        param = [self.set_slider_dict(0), self.set_itemtextctrl_dict(0)]
        self.m_slider1.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param))
        param = [self.set_slider_dict(1), self.set_itemtextctrl_dict(1)]
        self.m_slider2.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param))
        param = [self.set_slider_dict(2), self.set_itemtextctrl_dict(2)]
        self.m_slider3.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param))
        param = [self.set_slider_dict(3), self.set_itemtextctrl_dict(3)]
        self.m_slider4.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param))
        param = [self.set_slider_dict(4), self.set_itemtextctrl_dict(4)]
        self.m_slider5.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param))
        param = [self.set_slider_dict(5), self.set_itemtextctrl_dict(5)]
        self.m_slider6.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param))
        param = [self.set_slider_dict(6), self.set_itemtextctrl_dict(6)]
        self.m_slider7.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param))
        param = [self.set_slider_dict(7), self.set_itemtextctrl_dict(7)]
        self.m_slider8.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param))
        param = [self.set_slider_dict(8), self.set_itemtextctrl_dict(8)]
        self.m_slider9.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param))
        param = [self.set_slider_dict(9), self.set_itemtextctrl_dict(9)]
        self.m_slider10.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param))

同样修改无效,10个滑块同时响应的是最后一个滑块的滑块拉动数值。得到的结论是目前该种方式不能实现需求。分析发现是由于每个滑块控件的响应事件函数get_item_value()的输入参数都是取的最后一个param输入。

第三次尝试修改:

        param1 = [self.set_slider_dict(0), self.set_itemtextctrl_dict(0)]
        self.m_slider1.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param1))
        param2 = [self.set_slider_dict(1), self.set_itemtextctrl_dict(1)]
        self.m_slider2.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param2))
        param3 = [self.set_slider_dict(2), self.set_itemtextctrl_dict(2)]
        self.m_slider3.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param3))
        param4 = [self.set_slider_dict(3), self.set_itemtextctrl_dict(3)]
        self.m_slider4.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param4))
        param5 = [self.set_slider_dict(4), self.set_itemtextctrl_dict(4)]
        self.m_slider5.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param5))
        param6 = [self.set_slider_dict(5), self.set_itemtextctrl_dict(5)]
        self.m_slider6.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param6))
        param7 = [self.set_slider_dict(6), self.set_itemtextctrl_dict(6)]
        self.m_slider7.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param7))
        param8 = [self.set_slider_dict(7), self.set_itemtextctrl_dict(7)]
        self.m_slider8.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param8))
        param9 = [self.set_slider_dict(8), self.set_itemtextctrl_dict(8)]
        self.m_slider9.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param9))
        param10 = [self.set_slider_dict(9), self.set_itemtextctrl_dict(9)]
        self.m_slider10.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param10))

代码修改之后功能测试ok。

完整代码:

        # 拉动滑块事件
        param1 = [self.set_slider_dict(0), self.set_itemtextctrl_dict(0)]
        self.m_slider1.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param1))
        param2 = [self.set_slider_dict(1), self.set_itemtextctrl_dict(1)]
        self.m_slider2.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param2))
        param3 = [self.set_slider_dict(2), self.set_itemtextctrl_dict(2)]
        self.m_slider3.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param3))
        param4 = [self.set_slider_dict(3), self.set_itemtextctrl_dict(3)]
        self.m_slider4.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param4))
        param5 = [self.set_slider_dict(4), self.set_itemtextctrl_dict(4)]
        self.m_slider5.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param5))
        param6 = [self.set_slider_dict(5), self.set_itemtextctrl_dict(5)]
        self.m_slider6.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param6))
        param7 = [self.set_slider_dict(6), self.set_itemtextctrl_dict(6)]
        self.m_slider7.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param7))
        param8 = [self.set_slider_dict(7), self.set_itemtextctrl_dict(7)]
        self.m_slider8.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param8))
        param9 = [self.set_slider_dict(8), self.set_itemtextctrl_dict(8)]
        self.m_slider9.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param9))
        param10 = [self.set_slider_dict(9), self.set_itemtextctrl_dict(9)]
        self.m_slider10.Bind(wx.EVT_SCROLL, lambda evt: self.get_item_value(evt, param10))
        
    def set_slider_dict(self, idx):
        slider_list = [self.m_slider1, self.m_slider2, self.m_slider3, self.m_slider4, self.m_slider5,
                       self.m_slider6, self.m_slider7, self.m_slider8, self.m_slider9, self.m_slider10]
        slider_dict = {}
        for i in range(len(item_list)):
            slider_dict[i] = slider_list[i]
        return slider_dict[idx]

    def set_itemtextctrl_dict(self, idx):
        textctrl_list = [self.m_textCtrl2, self.m_textCtrl3, self.m_textCtrl4, self.m_textCtrl5,
                         self.m_textCtrl6, self.m_textCtrl7, self.m_textCtrl8, self.m_textCtrl9,
                         self.m_textCtrl10, self.m_textCtrl11]
        textctrl_dict = {}
        for i in range(len(item_list)):
            textctrl_dict[i] = textctrl_list[i]
        return textctrl_dict[idx]
        
    def get_item_value(self, event, param):
        item_value = param[0].GetValue()  # 返回int
        param[1].SetValue(str(item_value))

小结:目前修改之后的程序还是没有很好的实现“当输入对象的个数变化不是10个时,滑块的触发事件执行函数能够根据输入对象个数相应的获取对应的滑块slider控件和文本框textctrl控件“这个需求,滑块的响应事件设置还是需要一个个的手动设置,不能根据输入对象的个数实时变动。

参考链接:

  1. https://wiki.wxpython.org/Passing%20Arguments%20to%20Callbacks

  2. 【wxpython】Bind绑定带不定参

  3. wxPython-多个按钮使用同一个回调函数

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Logintern09

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值