现有窗口中的wxPython面板:慢和小

时间:2011-12-30 00:38:06

标签: python wxpython

我在创建wx.Panel时会遇到非常不同的行为,具体取决于主窗口是否已经调用Show()。

使用以下代码,应用程序可以快速打开,并创建MainPanel&在MainFrame.Show()之前填充。使用“新建”重新创建它具有多秒滞后,同时重新制作200个文本。此外,MainPanel不会展开以占用窗口的整个大小,直到调整窗口大小。

这绝对是面板创建而不是面板破坏的问题;如果我在MainFrame的init中删除MainPanel创建,那么New动作具有相同的速度&尺寸问题。

两个问题:

我可以做些什么来加快MainFrame.Show()之后的面板创建?

MainFrame.Show()之后创建MainPanel以使MainPanel扩展到其父级的大小时需要做什么?

#!/usr/bin/python
# -*- coding: utf-8 -*-

import wx
import wx.lib.scrolledpanel

class MainPanel(wx.lib.scrolledpanel.ScrolledPanel):
    def __init__(self,parent):
        wx.lib.scrolledpanel.ScrolledPanel.__init__(self, parent=parent)
        self.SetupScrolling()
        sizer = wx.BoxSizer(wx.VERTICAL)
        for i in range(1,200):
            sizer.Add(wx.StaticText(self, wx.ID_ANY, "I'm static text"))
        self.SetSizer(sizer)
        self.SetAutoLayout(True)

class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="FrameTest", size=(600,800))
        self.InitMenu()
        self.panel = None
        self.panel = MainPanel(self)

    def InitMenu(self):
        self.menuBar = wx.MenuBar()
        menuFile = wx.Menu()
        menuFile.Append(wx.ID_NEW, "&New")
        self.Bind(wx.EVT_MENU, self.OnNew, id=wx.ID_NEW)
        self.menuBar.Append(menuFile, "&File")
        self.SetMenuBar(self.menuBar)

    def OnNew(self, evt):
        if self.panel:
            self.panel.Destroy()
        self.panel = MainPanel(self)

if __name__ == "__main__":
    app = wx.App(0)
    frame = MainFrame()
    frame.Show()
    app.MainLoop()

UPDATE :joaquin的SendSizeEvent()绝对解决了第一个问题。对于第二个,我发现隐藏容器效果很好。我猜测在窗口显示之后,它试图在每个新窗口小部件之后不必要地重新(显示/布局/某些东西),这会减慢它的速度。如果我添加隐藏&显示到面板的init,然后没有滞后,它在两种情况下都有效。

class MainPanel(wx.lib.scrolledpanel.ScrolledPanel):
    def __init__(self,parent):
        wx.lib.scrolledpanel.ScrolledPanel.__init__(self, parent=parent)
        self.SetupScrolling()
        self.Hide()
        sizer = wx.BoxSizer(wx.VERTICAL)
        for i in range(1,200):
            sizer.Add(wx.StaticText(self, wx.ID_ANY, "I'm static text"))
        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        self.Show()

1 个答案:

答案 0 :(得分:1)

如果Frame感觉到SizeEvent,面板将获得正确的大小。所以这适用于你的第二个问题:

def OnNew(self, evt):
    if self.panel:
        self.panel.Destroy()
    self.panel = MainPanel(self)
    self.SendSizeEvent()

使用sizer可以更轻松地控制窗口和小部件。使用主框架中的sizer,您可以使用sizer Layout方法来适应小部件。

无法找到加速面板重写的方法。但是你可以通过不删除面板而是清除sizer来减少奇怪的视觉效果(在这种情况下你不需要SendSizeEvent()):

class MainPanel(wx.lib.scrolledpanel.ScrolledPanel):
    def __init__(self,parent):
        wx.lib.scrolledpanel.ScrolledPanel.__init__(self, parent=parent)
        self.SetupScrolling()
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.fill()
        self.SetSizer(self.sizer)

    def fill(self):
        tup = [wx.StaticText(self, wx.ID_ANY, "I'm static text") for i in range(200)]
        self.sizer.AddMany(tup)
        self.Layout()

class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="FrameTest", size=(600,800))
        self.InitMenu()
        self.panel = None
        self.panel = MainPanel(self)

    def InitMenu(self):
        self.menuBar = wx.MenuBar()
        menuFile = wx.Menu()
        menuFile.Append(wx.ID_NEW, "&New")
        self.Bind(wx.EVT_MENU, self.OnNew, id=wx.ID_NEW)
        self.menuBar.Append(menuFile, "&File")
        self.SetMenuBar(self.menuBar)

    def OnNew(self, evt):
        if self.panel:
            self.panel.sizer.Clear()
        self.panel.fill()