Dialog displays differently on Windows and OS X

Hi All,

I’m fiddling around with dialogs (wx.Dialog), and I’m seeing some interesting sizer behavior. Odds are I’m doing something silly, but I’m seeing this on Windows:

and this on OS X:

Obviously I’m aiming at the appearance under Windows for both platforms (will check Linux later). The layout I have (using sizers - see attached code) appears to be:

I’m still fiddling around with sizer flags, etc., but I’m wondering if there is any way to make the sizers visible when the dialog is running. If anyone spots anything that might explain the difference in behavior please sing out.

SystemConfigDlg.py (6.8 KB)


System Configs
Mac OS X 10.15.4 / Python 3.8.2 (from python.org) / wxPython 4.1.0 (via pip)

Windows 10 / Python 3.8.2 (from python.org) / wxPython 4.1.0 (via pip)

I’m not sure I see what the problem is. What are the differences that are bothering you?

There is a way you can make the sizers visible. Take a look at the Widget Inspection Tool. The image at the bottom of the page shows the result of clicking on the Highlight button after selecting the FlexGridSizer in the widget tree.

It doesn’t work very well with DIalogs because of the modal nature of the dialog, but you can switch the dialog you want to inspect to be derived from a wx.Panel, put it in a frame and then when you run the Inspector you can interact with it as needed.

The dialog on OS X has a large gap to the right that doesn’t appear in the Windows dialog. To be honest, I’m not sure where that’s coming from. :thinking:

I used your tip of putting everything into a top-level sizer from our last discussion on sizer madness to try to work around that sort of thing.

Thanks for the pointer to the tool. I’ll continue investigating…

Update: Just checked the sizers using the inspection tool. Nothing looked out of place with regard to the controls being properly placed in sizers. I intentionally let the dialog dynamically resize to try to account for the differences in the control sizes so the initial size setting for the dialog is smaller than the final size of the dialog. Is that not the recommended way to do that sort of thing?

Ah. I was mainly just looking at the layout of the widgets compared to each other, and not the overall picture.

Okay, I’ve taken a closer look and here’s what I’ve found.

  1. It’s the row_sizer that is pushing out the width.

  2. Some items in that sizer are added with proportion=1, so the unexpected extra width is likely because the proportional widths will be based on the largest item managed by the sizer.

  3. I notice you use wx.ALL or other side flags (TOP, BOTTOM, LEFT, RIGHT) without giving a margin value, making the use of those flags meaningless. Not part of the problem but maybe it indicates some misunderstanding about how they work.

  4. The row_sizer is added to the main_sizer without wx.EXPAND, so it will not be automatically expanded to the width of the other items in the main_sizer. I changed the wx.ALL on that line to wx.EXPAND.

  5. The stretch spacer inside the btn_sizer is superfluous, because the stretch spacer next to it in the parent sizer will take care of pushing the buttons to the right. Also, the btn_sizer should be added to the row_sizer with proportion=0 because it only needs to be as wide as the buttons, not steal space from the row_sizer, or cause it to be wider than needed.

Here are the changes I made to your sample code:

--- SystemConfigDlg.py.orig	2020-05-18 10:16:16.000000000 -0700
+++ SystemConfigDlg.py	2020-05-18 10:40:52.000000000 -0700
@@ -2,11 +2,11 @@
 import wx.grid


-class SystemConfigDlg(wx.Dialog):
+class SystemConfigDlg(wx.Panel):

     def __init__(self, parent):
-        super().__init__(parent, wx.ID_ANY, 'System Defaults', size=(640,320))
-
+        #super().__init__(parent, wx.ID_ANY, 'System Defaults') #, size=(640,320))
+        super().__init__(parent)

         self.__InitUI()

@@ -31,7 +31,7 @@
         # add the reviewer controls
         row_sizer = wx.BoxSizer()
         self.__add_reviewer_controls(panel, row_sizer)
-        main_sizer.Add(row_sizer, 0, wx.ALL)
+        main_sizer.Add(row_sizer, 0, wx.EXPAND)

         panel.SetSizer(main_sizer)

@@ -39,6 +39,7 @@
         self.SetSizer(top_sizer)
         self.Fit()

+
     def __add_adjustment_grid(self, panel, row_sizer):
         col_sizer = wx.BoxSizer(wx.VERTICAL)
         lbl = wx.StaticText(panel, label='Adjustments')
@@ -161,10 +162,27 @@

         # add the apply/cancel buttons
         btn_sizer = wx.BoxSizer()
-        btn_sizer.AddStretchSpacer(1)
+        ##btn_sizer.AddStretchSpacer(1)

         self.btn_sysconf_cancel = wx.Button(panel, wx.ID_CANCEL, label='Cancel')
         btn_sizer.Add(self.btn_sysconf_cancel, 1, wx.ALIGN_BOTTOM)
         self.btn_sysconf_apply = wx.Button(panel, wx.ID_APPLY, label='Apply')
         btn_sizer.Add(self.btn_sysconf_apply, 1, wx.ALIGN_BOTTOM)
-        row_sizer.Add(btn_sizer, 1, wx.ALL | wx.BOTTOM | wx.EXPAND)
+        row_sizer.Add(btn_sizer, 0, wx.EXPAND)
+
+
+
+app = wx.App()
+frame = wx.Frame(None, title="layout tester")
+panel = SystemConfigDlg(frame)
+frame.Sizer = wx.BoxSizer()
+frame.Sizer.Add(panel, 1, wx.EXPAND)
+frame.Fit()
+frame.Show()
+import wx.lib.inspection
+wx.lib.inspection.InspectionTool().Show()
+
+#dlg = SystemConfigDlg(None)
+#dlg.ShowModal()
+
+app.MainLoop()

Hi Robin,

Thanks. I think I was going a bit code-blind from looking at the code for too long and bouncing back and forth between operating systems.

Best regards,

Chuck