pythonwxpythonscrolledwindow

creating a wxpython scrolled window (frame) by an event


I am trying to create a new frame in a wxpanel by clicking a button.

Below is my code. It does not work. Scroll bars do not show up.

Can anyone help me? Thanks!

(update: A button is added in the new window)

import wx

class ftest(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY,
                          "test Panel", size=(800, 500), pos=(0,0))
        self.MainPanel = wx.Panel(self, wx.ID_ANY)
        self.btn1 = wx.Button(self.MainPanel, pos=(50,100), label="New Frame")
        self.btn1.Bind(wx.EVT_BUTTON, self.newFrame)

    def newFrame(self, event):
        self.new_window = wx.Frame(self, title='frame2', size=(500, 500), pos=(800,0))
        self.new_window.Show()
        self.scroll = wx.ScrolledWindow(self.new_window, -1)
        self.scroll.SetScrollbars(1, 1, 1600, 1400)
        self.btn2 = wx.Button(self.new_window, pos=(50,100), label="button2")

if __name__ == "__main__":
    app = wx.App(False)
    frame = ftest()
    frame.Show()
    app.MainLoop()

,

(update 2) based on Joran Beasley's code,

this code creates scroll bars, but the button2 is not shown. and the text widget does not work properly when scrolled.

import wx

class ftest(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY,
                          "test Panel", size=(800, 500), pos=(0,0))
        self.MainPanel = wx.Panel(self, wx.ID_ANY)
        self.btn1 = wx.Button(self.MainPanel, pos=(50,100), label="New Frame")
        self.btn1.Bind(wx.EVT_BUTTON, self.newFrame)

    def newFrame(self, event):
        self.new_window = wx.Frame(self, title='frame2', pos=(800,0))
        self.scroll = wx.ScrolledWindow(self.new_window, -1,size=(500,500))
        self.scroll.SetScrollbars(1, 1, 1600, 1400)
        self.new_window.Layout()
        self.new_window.Fit()
        self.new_window.Show()
        self.btn2 = wx.Button(self.new_window, pos=(50,100), label="button2")
        wx.StaticText(self.new_window, -1, 'test text', pos=(50, 200))

if __name__ == "__main__":
    app = wx.App(False)
    frame = ftest()
    frame.Show()
    app.MainLoop()

,

(update 3) I found my mistake. The widgets should be on the scroll object, not on the frame object. Layout() and Fit() are not required. so correct code is

import wx

class ftest(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY,
                          "test Panel", size=(800, 500), pos=(0,0))
        self.MainPanel = wx.Panel(self, wx.ID_ANY)
        self.btn1 = wx.Button(self.MainPanel, pos=(50,100), label="New Frame")
        self.btn1.Bind(wx.EVT_BUTTON, self.newFrame)

    def newFrame(self, event):
        self.new_window = wx.Frame(self, title='frame2', pos=(800,0),size=(500,500))
        self.scroll = wx.ScrolledWindow(self.new_window, -1)
        self.scroll.SetScrollbars(1, 1, 1600, 1400)
        #self.new_window.Layout()
        #self.new_window.Fit()
        self.new_window.Show()
        self.btn2 = wx.Button(self.scroll, pos=(50,100), label="button2")
        wx.StaticText(self.scroll, -1, 'test text', pos=(50, 200))

if __name__ == "__main__":
    app = wx.App(False)
    frame = ftest()
    frame.Show()
    app.MainLoop()

Solution

  • def newFrame(self, event):
        self.new_window = wx.Frame(self, title='frame2', size=(500, 500), pos=(800,0))
    
        self.scroll = wx.ScrolledWindow(self.new_window, -1)
        self.scroll.SetScrollbars(1, 1, 1600, 1400)
        self.new_window.Layout()
        self.new_window.Fit()
        self.new_window.Show()
    

    you need to layout the new window ... since you clearly want it to fill the 500,500 area you will need to use sizers

    def newFrame(self, event):
        self.new_window = wx.Frame(self, title='frame2', size=(500, 500), pos=(800,0))
        sz = wx.BoxSizer()
        sz.SetMinSize((500,500)) #force minimum size
        self.scroll = wx.ScrolledWindow(self.new_window, -1)
        sz.Add(self.scroll,1,wx.EXPAND)
        self.scroll.SetScrollbars(1, 1, 1600, 1400)
        self.new_window.SetSizer(sz)
        self.new_window.Layout()
        self.new_window.Fit()
        self.new_window.Show()
    

    or just force the size of the contained scrollwindow (which is what you normally do for scrolled windows)

    def newFrame(self, event):
        self.new_window = wx.Frame(self, title='frame2', pos=(800,0))
    
        self.scroll = wx.ScrolledWindow(self.new_window, -1,size=(500,500))
        self.scroll.SetScrollbars(1, 1, 1600, 1400)
        self.new_window.Layout()
        self.new_window.Fit()
        self.new_window.Show()