sdaau
sdaau

Reputation: 38681

Getting rid of scrollbars in wxPython Panel subclass?

I am trying to subclass Panel, and with the code below, I'm hitting this problem:

panel-test.png

On the right, a normal wx.Panel is instantiated, and as is visible, it has no scrollbars. On the left, the subclass TImagePanel is instantiated (in the same way as the wx.Panel) - and as is visible, there are two thin green lines, which is how MATE desktop on Ubuntu 14.04 shows scrollbars (if you hover over them, you get a scrollbar element, which is shown on the screenshot; this is on Ubuntu 14.04, MATE desktop, python 2.7, python-wxgtk2.8 2.8.12.1).

What can I do in TImagePanel to get rid of these scrollbars?

TImagePanel.py

import wx

# via https://www.blog.pythonlibrary.org/2010/03/18/wxpython-putting-a-background-image-on-a-panel/
class TImagePanel(wx.Panel):
  def __init__(self, parent, style):
    """Constructor"""
    wx.Panel.__init__(self, parent=parent, style=style)
    self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) #(wx.BG_STYLE_ERASE)
    self.frame = parent
    self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)

  def OnEraseBackground(self, evt):
    """
    Add a picture to the background
    """
    # yanked from ColourDB.py
    dc = evt.GetDC()

    if not dc:
      dc = wx.ClientDC(self)
      rect = self.GetUpdateRegion().GetBox()
      dc.SetClippingRect(rect)
    dc.SetBackground(wx.Brush(self.GetBackgroundColour())) # SO: 11766759
    dc.Clear()

paneltest.py

import wxversion
wxversion.select("2.8")
import wx, wx.html
import sys

from TImagePanel import TImagePanel

class Frame(wx.Frame):
  def __init__(self, *args, **kwds):
    kwds["style"] = wx.DEFAULT_FRAME_STYLE
    wx.Frame.__init__(self, *args, **kwds)

    self.label = wx.StaticText(self, wx.ID_ANY, "TImagePanel below left: ")
    bt_main = wx.Button(self, label="Click ME")
    bt_main.Bind(wx.EVT_BUTTON, self.BtnClickHandler)

    sizer_vmain_app = wx.BoxSizer(wx.VERTICAL)
    sizer_vmain_app.Add(self.label, proportion=0, flag=wx.EXPAND, border=0)
    sizer_vmain_app.Add(bt_main, proportion=0, flag=0, border=0)

    self.mypanel = TImagePanel(self, wx.ID_ANY)
    normpanel = wx.Panel(self, wx.ID_ANY)
    self.mypanel.SetBackgroundColour(wx.Colour(200, 200, 200))
    normpanel.SetBackgroundColour(wx.Colour(200, 200, 200))

    sizer_hpanel = wx.BoxSizer(wx.HORIZONTAL)
    sizer_hpanel.Add(self.mypanel, proportion=1, flag=wx.ALL|wx.EXPAND, border=10)
    sizer_hpanel.Add(normpanel, proportion=1, flag=wx.ALL|wx.EXPAND, border=10)
    sizer_vmain_app.Add(sizer_hpanel, proportion=1, flag=wx.EXPAND, border=0)

    self.SetSizer(sizer_vmain_app)
    self.Layout()

  def BtnClickHandler(self, event):
    print("Am clicked")

if __name__ == "__main__":
  app = wx.PySimpleApp(0)
  wx.InitAllImageHandlers()
  app_frame = Frame(None, wx.ID_ANY, "")
  app.SetTopWindow(app_frame)
  app_frame.Show()
  app.MainLoop()

Upvotes: 0

Views: 187

Answers (1)

sdaau
sdaau

Reputation: 38681

Right, I think I got it. Since, when I resize the window, the sizes of scrollbars don't change, this indicates the problem has nothing to do with size of inner content (there is no inner content here, to begin with).

After some attempts, I noticed this line of code:

self.mypanel = TImagePanel(self, wx.ID_ANY)

Apparently, this was copied from a normal wx.Panel instantiation, which has a signature __init__(self, parent, id, pos, size, style, name), where indeed, the argument after parent is id.

However, in my TImagePanel subclass, the constructor has a signature: __init__(self, parent, style). So basically, this wx.ID_ANY which should have referred to an ID, propagated as a style when the parent class is inititialized in the constructor! So, it enabled all kindsa things, and very possibly wx.ALWAYS_SHOW_SB which forces display of scrollbars.

All I needed to do, then, was to put in instead:

self.mypanel = TImagePanel(self, 0)

... since styles are apparently bitmasked, the "don't change style" flag should be 0 (I couldn't otherwise find a wx.NO_STYLE flag); or to be more explicit with a predefined wx style:

self.mypanel = TImagePanel(self, wx.NO_BORDER)

In either of these cases, the scrollbars disappear and the subclassed item looks identical to the wx.Panel instance, which is what I wanted to achieve in this case.

Upvotes: 1

Related Questions