在 wx.Listbook 内增加 ListCtrl 的宽度

Increase width of the ListCtrl within a wx.Listbook

我正在使用 wx.Listbook,它使用 ListCtrl 来 select 列表簿中的页面。但是,ListCtrl 的宽度小于最短的页面名称。我想增加宽度以使页面名称不被截断,但似乎不能。

当然,我可以使用 Listbook.GetListView() 访问 ListCtrl。但是,更改大小没有任何效果。我还尝试访问 ListCtrl 的 sizer(通过 myListCtr.GetContainingSizer())但是 returns None.

如何在 wx.Listbook 中增加 ListCtrl 的宽度?

import wx

class MyApp(wx.Frame):

    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Example")
        panel = wx.Panel(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.myListBook = wx.Listbook(panel, style=wx.LB_LEFT)

        # Access listCtr
        myListCtr = self.myListBook.GetListView()

        # Failed attempt to resize sizer
        # lcSizer = myListCtr.GetContainingSizer()
        # lcSizer.SetItemMinSize(myListCtr, 500, -1)

        # Second failed attempt
        # sizeritem = lcSizer.GetItem(self.myListCtr)
        # sizeritem.SetProportion(1)
        # sizeritem.SetMinSize(500, -1)

        # Resize ListCtr has to effect
        self.myListCtr.SetSize(500, -1)

        # Add a (blank) page with a long name
        page = wx.Panel(self.myListBook)
        self.myListBook.AddPage(page, "A Long Page Title")

        sizer.Add(self.myListBook, 1, wx.EXPAND | wx.ALL, 5)
        panel.SetAutoLayout(True)
        panel.SetSizer(sizer)
        sizer.Fit(panel)
        sizer.SetSizeHints(panel)
        panel.Layout()


if __name__ == "__main__":
    app = wx.App(False)
    frame = MyApp()
    frame.Show()
    app.MainLoop()

我是 运行 Windows 10,Python 3.8.1,wxPython 4.1.1 msw (phoenix) wxWidgets 3.1.5.

这似乎有效。请参阅我在 lb_width

上的注释
import wx


class MainFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(None, *args, **kwargs)
        self.Title = 'Wx App'

        self.panel = MainPanel(self)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.panel)
        self.SetSizer(sizer)
        self.Center()
        self.Show()


class MainPanel(wx.Panel):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)

        # This width affects the width of the lstctrl
        lb_width = 600
        self.myListBook = wx.Listbook(self, style=wx.LB_LEFT, size=(lb_width, 600))

        # Access listCtr
        page = wx.Panel(self.myListBook)
        self.myListBook.AddPage(page, "A Long Page Title. As long as you like")
        myListCtr = self.myListBook.GetListView()
        myListCtr.Size = (400, 500)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.myListBook)
        self.Layout()
        self.SetSizer(sizer)


if __name__ == '__main__':
    wx_app = wx.App()
    MainFrame()
    wx_app.MainLoop()

您需要为每个添加的页面设置一个sizer

import wx

class MyApp(wx.Frame):

    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Example")
        panel = wx.Panel(self, -1)

        self.myListBook = wx.Listbook(panel, -1, style=wx.LIST_FORMAT_LEFT)

        page1 = wx.Panel(self.myListBook, -1)
        self.myListBook.AddPage(page1, "A really............. Long Page Title")

        page1_stuff = wx.StaticText(page1, wx.ID_ANY, ("Items in the page 1"))
        page1_sizer = wx.BoxSizer(wx.VERTICAL)
        page1_sizer.Add(page1_stuff, 0, wx.EXPAND, 5)
        page1.SetSizer(page1_sizer)

        page2 = wx.Panel(self.myListBook, -1)
        self.myListBook.AddPage(page2, "Page 2")

        page2_stuff = wx.StaticText(page2, wx.ID_ANY, ("Items in the page 2"))
        page2_sizer = wx.BoxSizer(wx.VERTICAL)
        page2_sizer.Add(page2_stuff, 0, wx.EXPAND, 5)
        page2.SetSizer(page2_sizer)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.myListBook, 1, wx.EXPAND | wx.ALL, 5)
        panel.SetSizer(sizer)
        self.Layout()


if __name__ == "__main__":
    app = wx.App(False)
    frame = MyApp()
    frame.Show()
    app.MainLoop()

[Responding to your comments - 2nd Attempt]

我正在努力 make 这出问题了。
即使诉诸于删除 sizer 并固定 Listbook 大小,仍会继续按比例排列项目。

import wx

class MyApp(wx.Frame):

    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Example", size=(1000,700))
        panel = wx.Panel(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.myListBook = wx.Listbook(panel, -1, size=(350, 500))

        page = wx.Panel(self.myListBook)
        page.SetBackgroundColour('yellow')
        page_stuff = wx.StaticText(page, wx.ID_ANY, ("Item in the page 1"))
        page2 = wx.Panel(self.myListBook)
        page2.SetBackgroundColour('lightblue')
        self.myListBook.AddPage(page, "A Long Page Title ...............X")
        self.myListBook.AddPage(page2, "Another Long Page Title")

if __name__ == "__main__":
    app = wx.App(False)
    frame = MyApp()
    frame.Show()
    app.MainLoop()

您必须在 ListCtrl 添加所有页面后 SetColumnWidth。这将导致重新计算列宽,进而重新计算 ListCtrl 的总宽度。

myListCtrl = self.myListBook.GetListView()
myListCtrl.SetColumnWidth(0, -1)

我们可以将列宽设置为硬值,但是通过使用 -1 我们告诉它使用列表中最长项目的宽度来计算宽度。所以需要在添加完最后一页后调用。

这是一个完整的例子:

import wx

class MyApp(wx.Frame):

    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Example")
        panel = wx.Panel(self)

        self.myListBook = wx.Listbook(panel, size=(500, 500), style=wx.LIST_FORMAT_LEFT)

        page1 = wx.Panel(self.myListBook)
        self.myListBook.AddPage(page1, "A Long Page Title")

        page2 = wx.Panel(self.myListBook, -1)
        self.myListBook.AddPage(page2, "An Even Longer Page Title")

        page3 = wx.Panel(self.myListBook, -1)
        self.myListBook.AddPage(page3, "Page 3")

        # Access listCtr and calculate column width
        myListCtrl = self.myListBook.GetListView()
        myListCtrl.SetColumnWidth(0, -1)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.myListBook, 1, wx.EXPAND | wx.ALL, 5)
        panel.SetSizer(sizer)
        panel.Layout()


if __name__ == "__main__":
    app = wx.App(False)
    frame = MyApp()
    frame.Show()
    app.MainLoop()

这是 Windows 上的样子:

请注意,自动计算可能无法在每个应用程序中都按预期工作。在上面的示例应用程序中,直到添加最后一页并重新计算列宽后才绘制 ListBook。但是,在我遇到这个问题的实际应用程序中,ListBook 最初 drawn/rendered 到屏幕是空的,然后通过应用程序的正常使用页面是 added/removed。在这种情况下,在添加页面并调用 SetColumnWidth 后不会调整 ListCtrl 的大小,只会调整列的大小。如果该列增长到大于 ListCtrl,则会出现一个滚动条,允许用户滚动以查看项目的截断端。但是,如果列缩小,则右列边框会被拉到最长项目的末尾。虽然我可以调用重绘 ListBook,但这会使页面内容每次移动 left/right。相反,我只是在应用程序启动时将列宽设置为一个硬值。我只是选择了一个在大多数情况下适用于该应用程序上下文的值。