现有窗口中的 wxPython 面板:慢且小 [英] wxPython Panel in existing window: slow and small

查看:39
本文介绍了现有窗口中的 wxPython 面板:慢且小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据主窗口是否已调用 Show(),我在创建 wx.Panel 时遇到了非常不同的行为.

I'm experiencing very different behavior when creating a wx.Panel depending on whether the main window's already called Show().

使用下面的代码,应用程序快速打开并创建了 MainPanel &在 MainFrame.Show() 之前填充.使用新建"重新创建它在重新制作 200 个文本时会有几秒钟的延迟.此外,在调整窗口大小之前,MainPanel 不会扩展以占据窗口的整个大小.

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.

这绝对是面板创建而不是面板销毁的问题;如果我在 MainFrame 的 init 中删除 MainPanel 创建,则 New 操作具有相同的速度 &尺寸问题.

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.

两个问题:

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

Is there anything I can do to speed up panel creation after MainFrame.Show()?

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

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()

更新:joaquin 的 SendSizeEvent() 绝对解决了第一个问题.其次,我发现隐藏容器效果很好.我猜在显示窗口后,它会在每个新小部件之后尝试不必要地重新(显示/布局/某些东西),这会减慢它的速度.如果我添加 Hide &显示给面板的 init,然后就不再有延迟,并且在两种情况下都可以使用.

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()

推荐答案

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

The panel will get the correct size if the Frame feels a SizeEvent. So this works for your second question:

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

使用 sizer 可以更轻松地控制窗口和小部件.在主框架中使用 sizer,您可以使用 sizer Layout 方法将小部件放置到位.

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.

找不到加快面板重写的方法.但是您可以通过不删除面板而是清除 sizer 来减少奇怪的视觉效果(对于这种情况,您不需要 SendSizeEvent()):

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):

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()

这篇关于现有窗口中的 wxPython 面板:慢且小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆