微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

wxPython中的自定义可折叠列表,鼠标事件未传播到父级

如何解决wxPython中的自定义可折叠列表,鼠标事件未传播到父级

我正在使用wxPython编写GUI待办事项列表应用程序,并且需要包含可折叠项的列表。我了解wx.CollapsiblePanewx.lib.agw.foldpanelbar.FoldPanelBar,但都不会让您以复杂的方式自定义折叠项标签。我想要一个简单的待办事项标题以及一个可单击的复选框作为折叠视图,单击复选框的标签后,它会展开以显示注释,截止日期等。我已经使用静态文本创建了原型,但是即使那个也不起作用。使用复选框只会通过添加更多的鼠标事件侦听器使其变得更加复杂。

如果您仅在StaticText中使用ItemPanel窗口(已推出),则可以使用。 为什么它不适用于自定义面板类?

import wx

PADDING = 10

class App(wx.App):
    def OnInit(self):
        self.data = [
            {'title':'1st','content':'First'},{'title':'2nd','content':'Second'},{'title':'3rd','content':'Third'},]
        frame = ListFrame()
        frame.Show()
        self.SetTopWindow(frame)
        return True

class ListFrame(wx.Frame):
    def __init__(self,title="List",size=(250,500)):
        wx.Frame.__init__(self,None,-1,title=title,size=size)
        panel = wx.Panel(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(wx.StaticText(panel,label='List Title'),flag=wx.EXPAND|wx.ALL,border=PADDING)
        sizer.Add(wx.StaticLine(panel,style=wx.LI_HORIZONTAL),flag=wx.EXPAND)
        sizer.Add(ListPanel(panel),proportion=1,flag=wx.EXPAND)
        panel.SetSizer(sizer)

class ListPanel(wx.ScrolledWindow):
    def __init__(self,parent):
        super().__init__(parent)
        self.data = wx.GetApp().data
        self.SetScrollRate(0,5)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        for item in self.data:
            item_panel = ItemPanel(self,item)
            self.sizer.Add(item_panel,flag=wx.ALIGN_LEFT|wx.LEFT|wx.RIGHT|wx.BottOM,border=PADDING)
        self.SetSizer(self.sizer)

class ItemPanel(wx.Control):
    def __init__(self,parent,item):
        self.parent = parent
        super().__init__(self.parent)
        self.collapsed = True
        self.item = item

        self.sizer = wx.BoxSizer(wx.VERTICAL)

        #self.panel_collapsed = wx.StaticText(self,label='> '+item['title'])
        #self.panel_expanded = wx.StaticText(self,label='v '+item['title']+'\n\t'+item['content'])
        self.panel_collapsed = ItemPanelCollapsed(self)
        self.panel_expanded = ItemPanelExpanded(self)

        self.panel_collapsed.Bind(wx.EVT_LEFT_UP,self.OnToggleView)
        self.panel_expanded.Bind(wx.EVT_LEFT_UP,self.OnToggleView)
        #self.Bind(wx.EVT_LEFT_UP,self.OnToggleView)

        self.sizer.Add(self.panel_collapsed,flag=wx.EXPAND)
        self.sizer.Add(self.panel_expanded,flag=wx.EXPAND)
        self.sizer.Hide(self.panel_expanded)
        self.SetSizer(self.sizer)

    def OnToggleView(self,event):
        if self.collapsed:
            self.sizer.Hide(self.panel_collapsed)
            self.sizer.Show(self.panel_expanded)
        else:
            self.sizer.Hide(self.panel_expanded)
            self.sizer.Show(self.panel_collapsed)
        self.collapsed = not self.collapsed
        self.sizer.Layout()
        self.parent.sizer.Layout()

class ItemPanelCollapsed(wx.Control):
    def __init__(self,parent):
        super().__init__(parent,style=wx.BORDER_NONE)
        sizer = wx.BoxSizer(wx.VERTICAL)
        #sizer.Add(wx.CheckBox(self,label=parent.item['title']),flag=wx.EXPAND)
        sizer.Add(wx.StaticText(self,label='> '+parent.item['title']),flag=wx.EXPAND)
        self.SetSizer(sizer)

class ItemPanelExpanded(wx.Control):
    def __init__(self,label='v '+parent.item['title']),label=parent.item['content']),flag=wx.EXPAND)
        self.SetSizer(sizer)

if __name__ == '__main__':
    app = App(False)
    app.MainLoop()

我还尝试将鼠标事件绑定到子窗口的ItemPanel(已注释掉) 上,但是后来又无法正常工作了。所以我想这与how the mouse events are propagated up the chain有关。因此,我还尝试让所有自定义类都继承自wx.Panelwx.Window,但这并没有改变行为。

可选:由于我是wxPython的新手,如果您可以回答这些相关的样式问题,那就好了

  1. 这是完成任务的正确方法吗?我是否应该直接修改ItemPanel而不是隐藏/取消隐藏嵌套元素?
  2. 如果此方法在某种程度上是正确的,那么从ItemPane.OnToggleView改变“布局”布局的最佳方法是什么?将所有parent.sizer.Layout()调用到链上(想象更多的嵌套)似乎有些麻烦……
  3. 这是进行模型/视图分离的正确方法吗?将数据保存在App.data中,并使用wx.GetApp()从窗口访问数据。 App.data更改后,如何自动更新视图?
  4. 定义全局样式的正确方法是什么?我使用了模块范围的常量PADDING,但也许将其放入App并通过wx.GetApp()访问它会更好吗?但是基本上每个窗口都会调用函数吗?
  5. 在这种情况下要继承的正确类是什么?我将wx.Panel用于“高级”元素,将wx.Control用于更多的基本小部件。我不太了解wx.Windowwx.Panelwx.control间的区别(这就是为什么我从ListPanel继承它时将其称为wx.ScrolledWindow的原因)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。