简体   繁体   English

wxpython如何在调整窗口大小时防止BoxSizer崩溃?

[英]wxpython How to prevent BoxSizer from collapsing when window is resized?

I am using BoxSizer as a horizontal and vertical layout. 我使用BoxSizer作为水平和垂直布局。 However when I use a vertical BoxSizer in a horizontal BoxSizer to contain my buttons so it display vertically beside another element, and when you resize it, it collapse and hide the buttons until you expand it again. 但是,当我在水平BoxSizer使用垂直BoxSizer来包含我的按钮时,它在另一个元素旁边垂直显示,并且在调整其大小时,它会折叠并隐藏按钮,直到再次展开它。

Here is what it looks like by default 这是默认情况下的样子 在此处输入图片说明

and here is how it looks like after we resize it to a smaller width 这是我们将其调整为较小宽度后的样子 在此处输入图片说明

As you can see, the buttons is collapsed when resized. 如您所见,按钮在调整大小后会合拢。 How do you stop BoxSizer from being collapsed whenever the window is resized? 每当调整窗口大小时,如何阻止BoxSizer折叠?

Code

A sizer just lays out the elements using the available size. 大小调整器仅使用可用大小来布局元素。 If there is not enough of it, the sizer has no choice but to truncate (or even completely hide) some items. 如果没有足够的大小,则大小调整器别无选择,只能截断(甚至完全隐藏)某些项目。

To ensure that this doesn't happen, you must ensure that your window can't be made smaller than its minimal size. 为确保不会发生这种情况,必须确保您的窗口不能小于其最小尺寸。 This is done with SetMinClientSize() which is called by the convenient SetSizerAndFit() wrapper, neither of which is used in your code. 这是通过SetMinClientSize()完成的,该便捷的SetSizerAndFit()包装器调用了SetSizerAndFit() ,在您的代码中均未使用这两个包装。

Firstly, the semi-rigid rule of posting your code in the question, not on a link, is so that people can see if you have changed it, which you have! 首先,在问题中而不是在链接上发布代码的半刚性规则是,人们可以看到您是否更改了代码,这是您所拥有的!

Your code has now changed, so it becomes difficult to explain changes made to the original code and how they relate to the new code. 您的代码现已更改,因此很难解释对原始代码所做的更改以及它们与新代码的关系。

Basically, you have to pay special attention, when using sizers, to the proportion and wx.EXPAND flags. 基本上,使用大小调整器时,必须特别注意比例和wx.EXPAND标志。 They can cause all sorts of unintended consequences. 它们可能导致各种意想不到的后果。

Personally, I would probably have run with a different sizer, perhaps FlexGridSizer for this. 就个人而言,我可能会使用其他的大小调整器,也许是为此FlexGridSizer

Here is your original code, with the proportion and expand flags adjusted to perform what I assume you wanted. 这是您的原始代码,调整了proportion和扩展flags以执行我认为您想要的操作。

import wx
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin

#from processor import process_xls

class MainFrame(wx.Frame):

    TITLE = 'Neko'
    FRAME_MIN_SIZE = (600, 300)
    DEFAULT_BORDER_SIZE = 10

    INPUT_LABEL = 'Input files : '
    ADD_LABEL = 'Add'

    REMOVE_LABEL = 'Remove'
    START_LABEL = 'Start'

    FILE_LABEL = 'File'
    SIZE_LABEL = 'Size'
    PERCENT_LABEL = 'Percent'
    ETA_LABEL = 'ETA'
    SPEED_LABEL = 'Speed'
    STATUS_LABEL = 'Status'
    STATUS_LIST = {
        'filename': (0, FILE_LABEL, 120, True),
        'size': (1, SIZE_LABEL, 60, False),
        'percent': (2, PERCENT_LABEL, 80, False),
        'eta': (3, ETA_LABEL, 60, False),
        'speed': (4, SPEED_LABEL, 60, False),
        'status': (5, STATUS_LABEL, 90, False),
    }

    def __init__(self, *args, **kwargs):
        super(MainFrame, self).__init__(*args, **kwargs)

        self.SetTitle(self.TITLE)
        self.SetSize(self.FRAME_MIN_SIZE)

        self._panel = wx.Panel(self)
        self._vertical_box = wx.BoxSizer(wx.VERTICAL)

        # Inputs
        self._horizontal_box_input = wx.BoxSizer(wx.HORIZONTAL)

        self._tc_file_picker = wx.TextCtrl(self._panel)
        self._horizontal_box_input.Add(self._tc_file_picker,
                                    proportion=1, flag=wx.EXPAND)

        self._button_add = wx.Button(self._panel,
                                label=self.ADD_LABEL,
                                size=(-1,-1))
        self._button_add.Bind(wx.EVT_BUTTON,
                            self._on_add)
        self._horizontal_box_input.Add(self._button_add,
                                    flag=wx.LEFT,
                                    border=self.DEFAULT_BORDER_SIZE)

        self._vertical_box.Add(self._horizontal_box_input,
                            flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP,
                            border=self.DEFAULT_BORDER_SIZE)

        # Status List
        self._status_list = ListCtrl(self.STATUS_LIST,
                                parent=self._panel,
                                style=wx.LC_REPORT | wx.LEFT | wx.RIGHT)
        self._horizontal_box_status_list = wx.BoxSizer(wx.HORIZONTAL)
        self._horizontal_box_status_list.Add(self._status_list,
                                        proportion=1, flag=wx.EXPAND)

        status_list_buttons_data = {
            ('remove', self.REMOVE_LABEL, (-1, -1), self._on_remove, wx.Button),
            ('start', self.START_LABEL, (-1, -1), self._on_start, wx.Button),
        }

        # Create buttons vertically
        self._vertical_control_box = wx.BoxSizer(wx.VERTICAL)
        for item in status_list_buttons_data:
            name, label, size, evt_handler, parent = item

            button = parent(self._panel, size=size)

            if parent == wx.Button:
                button.SetLabel(label)

            if evt_handler is not None:
                button.Bind(wx.EVT_BUTTON, evt_handler)

            self._vertical_control_box.Add(button,
                                        flag=wx.LEFT|wx.BOTTOM|wx.EXPAND,
                                        proportion=1,
                                        border=self.DEFAULT_BORDER_SIZE)

        self._horizontal_box_status_list.Add(self._vertical_control_box)

        self._vertical_box.Add(self._horizontal_box_status_list,
                            flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP,
                            border=self.DEFAULT_BORDER_SIZE)

        # Set Sizer
        self._panel.SetSizerAndFit(self._vertical_box)

        #If you want the listctrl and textctrl to have a minimum size
        #open_size = self.GetSize()
        #self.SetMinSize(open_size)

        self.Show()

    def _on_add(self, event):
        pass

    def _on_remove(self, event):
        pass

    def _on_start(self, event):
        pass

class ListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin):
    def __init__(self, columns, *args, **kwargs):
        super(ListCtrl, self).__init__(*args, **kwargs)
        ListCtrlAutoWidthMixin.__init__(self)

        self.columns = columns
        self._set_columns()

    def _set_columns(self):
        for column_item in sorted(self.columns.values()):
            self.InsertColumn(column_item[0], column_item[1], width=wx.LIST_AUTOSIZE_USEHEADER)

            # If the column width obtained from wxLIST_AUTOSIZE_USEHEADER
            # is smaller than the minimum allowed column width
            # then set the column width to the minumum allowed size
            if self.GetColumnWidth(column_item[0]) < column_item[2]:
                self.SetColumnWidth(column_item[0], column_item[2])

            # Set auto-resize if enabled
            if column_item[3]:
                self.setResizeColumn(column_item[0])
if __name__ == "__main__":

    app = wx.App()
    MainFrame(None)
    app.MainLoop()

On open: 打开时: 在此处输入图片说明
On expand: 展开时: 在此处输入图片说明
On reduce: 减少: 在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM