【问题标题】:Wxpython panel is cropped with only a small box shown at the top left hand cornerWxpython 面板被裁剪,左上角仅显示一个小框
【发布时间】:2019-11-11 02:11:31
【问题描述】:

我正在使用 wx 中的 Hide() 和 Show() 来实现“下一页”效果,方法是隐藏一个面板并在同一帧中显示下一个面板(虽然不太确定我是否做得正确)。在某些页面,面板只是左上角的一个小裁剪版本,而其他一些面板可以正常工作(显示完整的东西)。我该如何解决这个问题?

我在 stackoverflow 上看到了有关面板或框架的子/父级的内容,并尝试更改我的代码,但它不起作用,不太确定如何正确执行。

class MyPanel(wx.Panel):
    def __init__(self, parent):
        #Constructor
        wx.Panel.__init__(self, parent=parent)
        #self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
        #This is for older versions of wx
        self.frame = parent
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
        self.Layout()

    def OnEraseBackground(self, evt):
        #Add background pic
        #From ColourDB.py
        dc = evt.GetDC()

        if not dc:
            dc = wx.ClientDC(self)
            rect = self.GetUpdateRegion().GetBox()
            dc.SetClippingRect(rect)
        dc.Clear()
        bmp = wx.Bitmap("RszHive.jpg")
        dc.DrawBitmap(bmp, 0, 0)

class StartPage(wx.Frame):
    def __init__(self, current_dt):
        #Settings for frame
        super().__init__(parent=None, title='Test', size=(850,790))
        #setting up main panel (home page)
        self.panel = MyPanel(self)
        self.current_dt = current_dt
        #so that frame will be in the center of the screen
        self.Center()

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

        from Database import DataBase, OperatingHours, GetDayTime, GetMenuByDayTime

        dDataBase = DataBase("Full_Menu_Database.txt")
        dOperatingHours = OperatingHours("Operating Hours.txt")

        # Convert to a tuple needed for the functions
        tDayTime = GetDayTime(self.get_dt())

        # Function to get menu dictionary by date and time
        # Will return an empty dictionary if no food/stores are available
        self.stores_open = GetMenuByDayTime(dDataBase, dOperatingHours, tDayTime)

        if self.stores_open == {}:
            self.ophours = wx.StaticText(self.panel, -1, style=wx.ALIGN_CENTER)
            self.ophours.SetLabel("Test")
            self.ophours_font = wx.Font(19, wx.TELETYPE, wx.NORMAL, wx.NORMAL)
            self.ophours.SetFont(self.ophours_font)
            self.vert_sizer.Add(self.ophours, 0, wx.ALL | wx.CENTER, 10)

        else:
            self.store_names, self.stores_ = [], []
            for onestorename in self.stores_open.keys():
                self.store_names.append(onestorename)
                self.stores_.append(self.stores_open[onestorename])

            #btn for store1
            store_btn1 = wx.Button(self.panel, label= self.store_names[0])
            store_btn1.Bind(wx.EVT_BUTTON, self.click_store1)
            self.vert_sizer.Add(store_btn1, 0, wx.ALL | wx.CENTER, 5)

            #btn for store2 if have
            if len(self.store_names) > 1:
                store_btn2 = wx.Button(self.panel, label=self.store_names[1])
                store_btn2.Bind(wx.EVT_BUTTON, self.click_store2)
                self.vert_sizer.Add(store_btn2, 0, wx.ALL | wx.CENTER, 5)

            # btn for store3 if have
            if len(self.store_names) > 2:
                store_btn3 = wx.Button(self.panel, label=self.store_names[2])
                store_btn3.Bind(wx.EVT_BUTTON, self.click_store3)
                self.vert_sizer.Add(store_btn3, 0, wx.ALL | wx.CENTER, 5)

            # btn for store4 if have
            if len(self.store_names) > 3:
                store_btn4 = wx.Button(self.panel, label=self.store_names[3])
                store_btn4.Bind(wx.EVT_BUTTON, self.click_store4)
                self.vert_sizer.Add(store_btn4, 0, wx.ALL | wx.CENTER, 5)

            # btn for store5 if have
            if len(self.store_names) > 4:
                store_btn5 = wx.Button(self.panel, label=self.store_names[4])
                store_btn5.Bind(wx.EVT_BUTTON, self.click_store5)
                self.vert_sizer.Add(store_btn5, 0, wx.ALL | wx.CENTER, 5)

        self.SetSizer(self.vert_sizer)
        self.Layout()
        self.Show()

Picture of what the panel looks like when i run the code

【问题讨论】:

  • 你必须创建一个 Sizer(简单的 BoxSizer 应该在这里做),将面板添加到它并在框架上调用 SetSizer。
  • @MichaelButscher 很抱歉,我没有在此处包含代码,但我确实创建了一个在其他页面上运行良好的 sizer,它仅对某些页面不起作用,所以我认为这不是 sizer 问题
  • @noyes,你应该在 Hide()/Show() 对调用之后调用 Layout()

标签: python wxpython panel wxwidgets frame


【解决方案1】:

@igor 是正确的,调用Layout 将完成工作。
这是一个例子: 单击显示的面板以切换到另一个面板。

import wx

class MyPanel(wx.Panel):
    def __init__(self, parent):
        super().__init__(parent)
        self.parent = parent

        self.panel = wx.Panel(self)
        self.btn = wx.Button(self.panel, label="Panel 1", size=(250,75))
        self.btn.Bind(wx.EVT_BUTTON, self.switch)

        vbox1 = wx.BoxSizer(wx.VERTICAL)
        vbox1.Add(self.btn)
        self.panel.SetSizer(vbox1)

        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self.panel)
        self.SetSizer(vbox)

        self.Show()

    def switch(self, event):
        self.parent.Swap()

class MyOtherPanel(wx.Panel):
    def __init__(self, parent):
        super().__init__(parent)
        self.parent = parent

        self.panel = wx.Panel(self)
        self.btn = wx.Button(self.panel, label="Panel 2", size=(175,250))
        self.btn.Bind(wx.EVT_BUTTON, self.switch)

        vbox1 = wx.BoxSizer(wx.VERTICAL)
        vbox1.Add(self.btn)
        self.panel.SetSizer(vbox1)

        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self.panel)
        self.SetSizer(vbox)

        self.Show()
        self.panel.Hide()

    def switch(self, event):
        self.parent.Swap()

class PanelSwitcher(wx.Frame):
    def __init__(self):
        super().__init__(None)

        vbox = wx.BoxSizer(wx.VERTICAL)
        self.panel1 = MyPanel(self)
        self.panel2 = MyOtherPanel(self)
        vbox.Add(self.panel1)
        vbox.Add(self.panel2)
        self.SetSizer(vbox)
        self.Show()

    def Swap(self):
        if self.panel1.panel.IsShown():
            self.panel1.panel.Hide()
            self.panel2.panel.Show()
        else:
            self.panel2.panel.Hide()
            self.panel1.panel.Show()
        self.Layout()


if __name__ == "__main__":
    app = wx.App()
    PanelSwitcher()
    app.MainLoop()

【讨论】:

    【解决方案2】:

    我也遇到这个问题很久了,不知道解决办法。尺寸调整器不起作用(如我所料)

    对我来说,问题是面板没有(或尺寸不正确)。解决方案是eiter:

    panel.Fit() 或者 panel.SetSize(x,y)

    另一种可能性是,首先将面板添加到 sizer 中。然后将它们设置为框架。 然后将按钮放入sizer - 并将它们添加到面板中。 这也解决了面板尺寸不正确的问题。

    【讨论】:

    • 我认为您可能能够提高答案的质量,一些示例可能有用。
    猜你喜欢
    • 2021-04-03
    • 2016-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    • 2023-04-08
    • 1970-01-01
    相关资源
    最近更新 更多