现有窗口中的 wxPython 面板:缓慢且小
在创建 wx.Panel 时,我遇到了非常不同的行为,具体取决于主窗口是否已调用 Show()。
使用下面的代码,应用程序可以快速打开并创建 MainPanel 并创建主面板。在 MainFrame.Show()
之前填充。使用“新建”重新创建它在重新制作 200 条文本时会出现多秒的延迟。此外,在调整窗口大小之前,MainPanel 不会扩展以占据窗口的整个大小。
这绝对是面板创建的问题,而不是面板破坏的问题;如果我在 MainFrame 的 init 中删除 MainPanel 创建,则“新建”操作具有相同的速度和速度。尺寸问题。
有两个问题:
在 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()
更新:joaquin的SendSizeEvent()绝对解决了第一个问题。对于第二点,我发现隐藏容器效果很好。我猜测在显示窗口后,它会在每个新小部件之后尝试不必要地重新(显示/布局/某些内容),这会减慢速度。如果我添加隐藏&显示给面板的初始化,然后就不再有延迟,并且在两种情况下都有效。
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()
I'm experiencing very different behavior when creating a wx.Panel depending on whether the main window's already called Show().
With the below code, the application opens quickly with MainPanel created & populated before MainFrame.Show()
. Using "New" to re-create it has multi-second lag while it re-makes the 200 texts. Also the MainPanel doesn't expand to take up the whole size of the window until the window is resized.
This is definitely an issue with panel creation rather than panel destruction; if I remove the MainPanel creation in MainFrame's init, then the New action has the same speed & size issues.
Two questions:
Is there anything I can do to speed up panel creation after MainFrame.Show()
?
What needs to be done when creating MainPanel after MainFrame.Show()
ed to have the MainPanel expand to the size of its parent?
#!/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's SendSizeEvent() definitely solves the first problem. For the second, I've found that hiding containers works out well. I'm guessing that after the window's been shown, it's trying to unnecessarily re-(display/layout/something) after every new widget and that's slowing it down. If I add Hide & Show to the panel's init, then there's no more lag and it works in both situations.
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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果 Frame 感受到 SizeEvent,面板将获得正确的尺寸。所以这适用于你的第二个问题:
通过使用 sizer 来控制窗口和小部件变得更容易。通过主框架中的 sizer,您可以使用 sizer
Layout
方法来将小部件安装到位。找不到加速面板重写的方法。但是您可以通过不删除面板而是清除 sizer 来减少奇怪的视觉效果(在这种情况下您不需要
SendSizeEvent()
):The panel will get the correct size if the Frame feels a SizeEvent. So this works for your second question:
Control of windows and widgets becomes easier by using sizers. With sizers in your main frame you can use the sizer
Layout
method to fit widgets in place.Could not find a way of speeding up panel rewrite. But you can diminish the bizarre visual effect by not deleting the panel but clearing the sizer instead (you dont need
SendSizeEvent()
for this case):