Search code examples
wxpython

wxPython simple GUI proving elusive


I have been working on Python 3.8 and wxPython 4 (Phoenix) on GNU/Linux for a number of days and I am making very little progress. I need a very simple GUI, with a scrolled canvas taking the majority of a full-screen window and a scrolled panel holding about 4 lines of text below that. I want some margin around the canvas and panel. I would like to be able to the positioning automatically (and not absolutely). Problems I am encountering are 1) the scroll bars are not appearing, 2) I am using absolute positioning and I am not really sure the sizer I place is even functioning.

I have been hacking around, trying all sorts of variations. I have read over the API documentation for all calls I use. I have looked at demos and samples. I have looked at every book I can find on O'Reilly. I still feel like I am quite a bit in the dark on understanding the architecture of wxPython. I have developed many other GUI apps in Python in TkInter and Qt, and in other languages. So, I'm feeling pretty dense here.

Here is what the current app looks like:

current app appearance

And here is my current code:

#!/usr/bin/env python3.8

import wx

class MainWindow(wx.Frame):

  def __init__(self, title):

    screen_x = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X)
    screen_y = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
    size_value = wx.Size(screen_x, screen_y)

    wx.Frame.__init__(self, None, title=title, size=size_value)
    # why does this not work?
    # super(MainWindow, self).__init__(self, None, title=title,
    #                                  size=size_value)

    canvas1 = wx.ScrolledCanvas(self, size=wx.Size(screen_x-30, 300),
                                pos=wx.Point(15, 15))
    canvas1.SetBackgroundColour('#cc20cc')
    canvas1.AlwaysShowScrollbars(True, True)
    canvas1.SetAutoLayout(1)
    canvas1.SetScrollbar(wx.VERTICAL, 0, 10, 100)
    canvas1.SetScrollbar(wx.HORIZONTAL, 0, 10, 100)
    canvas1.SetScrollRate(1, 1)

    # with open('/home/kbuchs/.emacs') as fp:
    #     txt_value = fp.read()
    # txt = wx.StaticText(canvas1, label=txt_value)

    canvas2 = wx.ScrolledCanvas(self, size=wx.Size(screen_x-30, 1000),
                                pos=wx.Point(15, 315))
    canvas2.SetBackgroundColour('#d0d020')
    canvas2.AlwaysShowScrollbars(True, True)
    canvas2.SetAutoLayout(1)
    canvas2.SetScrollRate(1, 1)

    with open('/home/kbuchs/.bashrc') as fp:
        txt_value2 = fp.read()
    txt2 = wx.StaticText(canvas2, label=txt_value2)

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

    sizer.Add(canvas1, wx.ID_ANY, wx.ALL, 20)
    sizer.Add(canvas2, wx.ID_ANY, wx.ALL, 40)

    self.Show()


app = wx.App()
MainWindow('Git Branch History')
app.MainLoop()

Update 6/3 10:30 PM CDT. Here is my latest revision-attempt at the code after the example by Rolf of Saxony. It appears the two txt sections (if uncommented) are not getting written into the canvas/panels, but both are overlapping at the top of the frame. Also, still no scrolling.

#!/usr/bin/env python3.8

import wx
import wx.lib.scrolledpanel as sp

class MainWindow(wx.Frame):

  def __init__(self, title):

    screen_x = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X)
    screen_y = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
    size_value = wx.Size(screen_x, screen_y)

    super(MainWindow, self).__init__(None, title=title, size=size_value)

    # canvas1 = wx.ScrolledCanvas(self, id=-1,
    canvas1 = sp.ScrolledPanel(self, id=-1,
                               size=wx.Size(screen_x, screen_y-200))
                                # pos=wx.Point(15, 15))
    canvas1.SetBackgroundColour('#ccffff')
    canvas1.AlwaysShowScrollbars(True, True)
    canvas1.SetAutoLayout(1)
    canvas1.SetupScrolling()

    with open('/home/kbuchs/.emacs') as fp:
        txt_value1 = fp.read()
    long_line = 900*'-' + '\n'
    # txt1 = wx.StaticText(canvas1, label=long_line+txt_value1)
    # txt1.SetBackgroundColour('#eeffff')

    # txt1Sizer = wx.BoxSizer(wx.VERTICAL)
    # txt1Sizer.Add(txt1, proportion=0, border=5)

    canvas1Sizer = wx.BoxSizer(wx.VERTICAL)
    canvas1Sizer.Add(canvas1, proportion=0, flag=wx.CENTER|wx.ALL|wx.EXPAND, border=5)
    # canvas1Sizer.Add(txt1Sizer, proportion=0)
    # canvas1Sizer.Add(txt1, proportion=0, flag=wx.ALL, border=5)

    # canvas2 = wx.ScrolledCanvas(self, id=-1,
    canvas2 = sp.ScrolledPanel(self, id=-1,
                               size=wx.Size(screen_x, 200))
                                # pos=wx.Point(15, 315))

    canvas2.SetBackgroundColour('#ffffcc')
    canvas2.AlwaysShowScrollbars(True, True)
    canvas2.SetAutoLayout(1)
    canvas2.SetupScrolling()

    with open('/home/kbuchs/.bashrc') as fp:
        txt_value2 = fp.read()
    # txt2 = wx.StaticText(canvas2, label=long_line+txt_value2)
    # txt2.SetBackgroundColour('#ffffee')

    canvas2Sizer = wx.BoxSizer(wx.VERTICAL)
    canvas2Sizer.Add(canvas2, proportion=0, flag=wx.CENTER|wx.ALL|wx.EXPAND, border=5)
    # canvas2Sizer.Add(txt2, proportion=0, flag=wx.CENTER|wx.ALL, border=20)

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

    sizer.Add(canvas1Sizer, proportion=0, flag=wx.CENTER|wx.ALL|wx.EXPAND, border=5)
    sizer.Add(canvas2Sizer, proportion=0, flag=wx.CENTER|wx.ALL|wx.EXPAND, border=5)

    self.Show()


app = wx.App()
MainWindow('Git Branch History')
app.MainLoop()

Solution

  • I'll take another stab at this, as you amended the question but did't make a comment, so I wasn't aware of it.
    You seem to have a blindspot for SetSizer, mentioned twice in comments and used in my first answer.
    It's like packing your suitcase and then going on holiday with your rucksack.

    Here is is your second code example, amended.

    import wx
    import wx.lib.scrolledpanel as sp
    
    class MainWindow(wx.Frame):
    
      def __init__(self, title):
    
        screen_x = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X)
        screen_y = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
        size_value = wx.Size(screen_x, screen_y)
    
        super(MainWindow, self).__init__(None, title=title, size=size_value)
    
        canvas1 = sp.ScrolledPanel(self, id=-1,)
    
        canvas1.SetBackgroundColour('#ccffff')
        canvas1.SetupScrolling(scroll_x=True, scroll_y=True, rate_x=20, rate_y=20, scrollToTop=True, scrollIntoView=True)
        canvas1.AlwaysShowScrollbars(True, True)
    
        with open('tips.txt') as fp:
            txt_value1 = fp.read()
        long_line = 600*'y' + 'X\n'
        txt1 = wx.StaticText(canvas1, label=long_line+txt_value1)
        txt1.SetBackgroundColour('#eeffff')
    
        canvas1Sizer = wx.BoxSizer(wx.VERTICAL)
        canvas1Sizer.Add(txt1, proportion=0, flag=wx.ALL|wx.EXPAND, border=5)
    
        canvas2 = sp.ScrolledPanel(self, id=-1)
    
        canvas2.SetBackgroundColour('#ffffcc')
        canvas2.SetupScrolling(scroll_x=True, scroll_y=True, rate_x=20, rate_y=20, scrollToTop=True, scrollIntoView=True)
        canvas2.AlwaysShowScrollbars(True, True)
    
        with open('tips.txt') as fp:
            txt_value2 = fp.read()
        txt2 = wx.StaticText(canvas2, label=long_line+txt_value2)
        txt2.SetBackgroundColour('#ffffee')
    
        canvas2Sizer = wx.BoxSizer(wx.VERTICAL)
        canvas2Sizer.Add(txt2, proportion=0, flag=wx.ALL|wx.EXPAND, border=20)
    
        canvas1.SetSizer(canvas1Sizer)
        canvas2.SetSizer(canvas2Sizer)
    
        sizer = wx.BoxSizer(wx.VERTICAL)
    
        sizer.Add(canvas1, proportion=1, flag=wx.ALL|wx.EXPAND, border=5)
        sizer.Add(canvas2, proportion=1, flag=wx.ALL|wx.EXPAND, border=5)
    
        self.SetSizer(sizer)
    
        self.Show()
    
    app = wx.App()
    MainWindow('Git Branch History')
    app.MainLoop()
    

    enter image description here