Phoenix
Phoenix copied to clipboard
Problem setting frame position in __init__ to (0, 0) on Linux
Operating system: Linux Mint 20.3 wxPython version & source: wxPython 4.1.1 gtk3 (phoenix) wxWidgets 3.1.5 (built from https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-20.04 using pip). Python version & source: Python 3.8.10 from Linux Mint distribution.
Description of the problem: If I call self.SetPosition((0, 0))
in the __init__()
method of a class derived from wx.Frame, the frame is not displayed at (0, 0) in most cases.
When I run the example code below and click the "Get Position" button, it consistently prints the coordinates "(158, 48)" to stdout. If I click the "Set Position" button the frame does move to (0, 0).
The only cases where this doesn't happen is when there is already another window covering the area around (158, 48), in which case the frame does appear at (0, 0). [I originally thought that the cases where the frame did appear at (0, 0) was somehow related to the virtual workspace the application was running in, but that was incorrect - it just happens if there is another window in the wrong place].
If I change the coordinates in the SetPosition()
call in __init__()
to anything other than (0, 0) e.g. (1, 0) or (0, 1), the frame will always be displayed at the specified position. It's only when using the coordinates (0, 0) that the problem occurs.
A workaround that I have found is to replace the SetPosition((0, 0))
call in __init__()
with the following lines:
self.SetPosition((1, 0))
wx.CallAfter(self.SetPosition, (0, 0))
This does work, but you can sometimes see the frame 'jump' position slightly.
Code Example (click to expand)
import wx
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.SetSize((400, 300))
self.SetTitle("Test Frame Position")
self.panel = wx.Panel(self, wx.ID_ANY)
sizer = wx.BoxSizer(wx.VERTICAL)
self.get_position_button = wx.Button(self.panel, wx.ID_ANY, "Get Position")
sizer.Add(self.get_position_button, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, 50)
self.set_position_button = wx.Button(self.panel, wx.ID_ANY, "Set Position")
sizer.Add(self.set_position_button, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, 50)
self.panel.SetSizer(sizer)
self.Layout()
self.Bind(wx.EVT_BUTTON, self.OnGetPosition, self.get_position_button)
self.Bind(wx.EVT_BUTTON, self.OnSetPosition, self.set_position_button)
self.SetPosition((1, 0))
def OnGetPosition(self, _event):
print(self.GetPosition())
def OnSetPosition(self, _event):
self.SetPosition((0, 0))
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame(None, wx.ID_ANY, "")
self.SetTopWindow(self.frame)
self.frame.Show()
return True
if __name__ == "__main__":
app = MyApp(0)
app.MainLoop()