I want to have scrollbars in a wxpython object that the user cannot navigate away from. Like how a dialog works. I want the scrollable area to be have comboboxes on it. I understand that I can easily put a scrollable area on a dialog that includes text.

The only way I can think to do this is to put the scrollable area on a frame, but the user then can navigate way from it which I do not want.

Can you not have scrollbars on dialogs?

Thanks for any help...I really can't figure this out...

Dani AI

Generated

— yes, a modal dialog can hold a scrollable area. was right that a custom dialog is the way to go, and 's pointer to a scrolled widget is on track. A practical, low-friction pattern is to put a wx.lib.scrolledpanel.ScrolledPanel inside a wx.Dialog, add your comboboxes and other controls to the panel's sizer, call the panel's SetupScrolling(), and present the dialog with ShowModal() so the user cannot interact with the main window while the dialog is open (, general docs: wxPython docs).

The ScrolledPanel approach avoids manually computing virtual sizes and virtual scrolling that you run into when using raw wx.ScrolledWindow and SetScrollbars. ScrolledPanel works with sizers: add children to the panel, then call SetupScrolling() (after all children are added), then SetSizerAndFit on the dialog or call Fit()/Layout() so the dialog and scroll region are calculated correctly.

Example pattern (not the same code posted earlier):

import wx
import wx.lib.scrolledpanel as scrolled

class MyScrolledDialog(wx.Dialog):
    def __init__(self, parent):
        super().__init__(parent, title="Scrolled Dialog", size=(420,340))
        sp = scrolled.ScrolledPanel(self)
        content = wx.BoxSizer(wx.VERTICAL)
        # add comboboxes / widgets to `content` here
        sp.SetSizer(content)
        sp.SetupScrolling()
        dlg_sizer = wx.BoxSizer(wx.VERTICAL)
        dlg_sizer.Add(sp, 1, wx.EXPAND)
        dlg_sizer.Add(self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL), 0, wx.EXPAND|wx.ALL, 5)
        self.SetSizerAndFit(dlg_sizer)

# show modally:
# dlg = MyScrolledDialog(parent); dlg.ShowModal(); dlg.Destroy()

Troubleshooting tips: call SetupScrolling only after adding all children; use SetSizerAndFit or Fit to force layout; ensure the scrolled panel is given proportion=1/EXPAND in the dialog sizer so it can grow and show scrollbars. Using ShowModal() keeps the dialog modal so the user cannot navigate away from it.

Recommended Answers

All 3 Replies

If you roll your own dialog box instead of using the standard offerings you can put anything you'd like on it...

If you roll your own dialog box instead of using the standard offerings you can put anything you'd like on it...

I assume what you mean by that is to create a custom dialog. Something like this:

class MyDialog(wx.Dialog):
    def __init__(self, parent, id, title):
        wx.Dialog.__init__(self, parent, id, title)

The problem is that I do not know what to do now. In a frame, I can do this to get scrollbars:

import wx

class ScrollbarFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'Scrollbar Example', size=(300, 200))
        self.scroll = wx.ScrolledWindow(self, -1)
        self.scroll.SetScrollbars(1, 1, 600, 400)
    
app = wx.PySimpleApp()
frame = ScrollbarFrame()
frame.Show()
app.MainLoop()

But, this does not work in a dialog.

How do I do this in a custom dialog?

Thank you very much for your help.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.