wxPython 如何在状态栏中设置小部件位置
wxPython how to set widget position inside statusbar
我想在状态栏中添加两个按钮,我将它们实现如下:
import wx
class MainFrame(wx.Frame):
"""Constructor"""
def __init__(self, parent, id):
wx.Frame.__init__(self, None)
# self.status_bar = self.CreateStatusBar(3)
self.status_bar = self.CreateStatusBar(3)
self.status_bar.SetStatusText("some text", 0)
self.button1 = wx.Button(self.status_bar, -1, "button 1")
self.button2 = wx.Button(self.status_bar, -1, "button 2")
self.status_bar.SetStatusWidths([-1, 200, 200])
self.button1.SetPosition((self.status_bar.Size[0]-100, 0))
self.button2.SetPosition((self.status_bar.Size[0]-200, 0))
self.Refresh()
self.Show()
if __name__ == "__main__":
app = wx.App()
MainFrame(None, -1)
app.MainLoop()
问题是:我不知道如何正确设置按钮的位置。
对于上面的示例,我已经为它们设置了两个插槽,但我无法将它们放入插槽中。相反,我必须使用 "SetPosition" 函数来设置按钮的固定位置,但是一旦 window 调整大小,按钮将留在那里并且不会被看到。
我想知道是否有一种简单的方法来设置状态栏内按钮的位置,就像我们使用 "self.status_bar.SetStatusText(self.button1, 1)" 和 "self.status_bar.SetStatusText(self.button2, 2)"
设置文本一样
非常感谢!
============================================= ==============================
非常感谢 Mike Driscoll 的回答,我找到了解决方法。
我将 post 我的解决方案如下,以防有人需要它。
import wx
class MyStatusBar(wx.StatusBar):
def __init__(self, parent):
wx.StatusBar.__init__(self, parent)
self.SetFieldsCount(3)
self.SetStatusWidths([-1, 200, 200])
self.sizeChanged = False
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_IDLE, self.OnIdle)
# Field 0 ... just text
self.SetStatusText("some text", 0)
# Field for buttons
self.button1 = wx.Button(self, 1001, "button 1")
self.button2 = wx.Button(self, 1002, "button 2")
# set the initial position of the checkbox
self.Reposition()
def OnSize(self, evt):
evt.Skip()
self.Reposition() # for normal size events
# Set a flag so the idle time handler will also do the repositioning.
# It is done this way to get around a buglet where GetFieldRect is not
# accurate during the EVT_SIZE resulting from a frame maximize.
self.sizeChanged = True
def OnIdle(self, evt):
if self.sizeChanged:
self.Reposition()
# reposition the buttons
def Reposition(self):
rect1 = self.GetFieldRect(1)
rect1.x += 1
rect1.y += 1
self.button1.SetRect(rect1)
rect2 = self.GetFieldRect(2)
rect2.x += 1
rect2.y += 1
self.button2.SetRect(rect2)
self.sizeChanged = False
class MainFrame(wx.Frame):
"""Constructor"""
def __init__(self, parent, id):
wx.Frame.__init__(self, None)
self.status_bar = MyStatusBar(self)
self.SetStatusBar(self.status_bar)
self.Refresh()
self.Show()
if __name__ == "__main__":
app = wx.App()
MainFrame(None, -1)
app.MainLoop()
最简单的方法是继承 wx.StatusBar 本身,添加按钮,然后捕获 wx.EVT_SIZE
。这样您就可以捕获调整大小事件并可以根据需要重新定位小部件。
wxPython 演示有一个示例,其中有一个复选框小部件,方法如下:
# reposition the checkbox
def Reposition(self):
rect = self.GetFieldRect(1)
rect.x += 1
rect.y += 1
self.cb.SetRect(rect)
self.sizeChanged = False
self.GetFieldRect(1)
指的是复选框小部件。您可以使用类似这样的东西,但您需要跟踪两个小部件的位置并相应地更新。
我想在状态栏中添加两个按钮,我将它们实现如下:
import wx
class MainFrame(wx.Frame):
"""Constructor"""
def __init__(self, parent, id):
wx.Frame.__init__(self, None)
# self.status_bar = self.CreateStatusBar(3)
self.status_bar = self.CreateStatusBar(3)
self.status_bar.SetStatusText("some text", 0)
self.button1 = wx.Button(self.status_bar, -1, "button 1")
self.button2 = wx.Button(self.status_bar, -1, "button 2")
self.status_bar.SetStatusWidths([-1, 200, 200])
self.button1.SetPosition((self.status_bar.Size[0]-100, 0))
self.button2.SetPosition((self.status_bar.Size[0]-200, 0))
self.Refresh()
self.Show()
if __name__ == "__main__":
app = wx.App()
MainFrame(None, -1)
app.MainLoop()
问题是:我不知道如何正确设置按钮的位置。 对于上面的示例,我已经为它们设置了两个插槽,但我无法将它们放入插槽中。相反,我必须使用 "SetPosition" 函数来设置按钮的固定位置,但是一旦 window 调整大小,按钮将留在那里并且不会被看到。
我想知道是否有一种简单的方法来设置状态栏内按钮的位置,就像我们使用 "self.status_bar.SetStatusText(self.button1, 1)" 和 "self.status_bar.SetStatusText(self.button2, 2)"
设置文本一样非常感谢!
============================================= ==============================
非常感谢 Mike Driscoll 的回答,我找到了解决方法。 我将 post 我的解决方案如下,以防有人需要它。
import wx
class MyStatusBar(wx.StatusBar):
def __init__(self, parent):
wx.StatusBar.__init__(self, parent)
self.SetFieldsCount(3)
self.SetStatusWidths([-1, 200, 200])
self.sizeChanged = False
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_IDLE, self.OnIdle)
# Field 0 ... just text
self.SetStatusText("some text", 0)
# Field for buttons
self.button1 = wx.Button(self, 1001, "button 1")
self.button2 = wx.Button(self, 1002, "button 2")
# set the initial position of the checkbox
self.Reposition()
def OnSize(self, evt):
evt.Skip()
self.Reposition() # for normal size events
# Set a flag so the idle time handler will also do the repositioning.
# It is done this way to get around a buglet where GetFieldRect is not
# accurate during the EVT_SIZE resulting from a frame maximize.
self.sizeChanged = True
def OnIdle(self, evt):
if self.sizeChanged:
self.Reposition()
# reposition the buttons
def Reposition(self):
rect1 = self.GetFieldRect(1)
rect1.x += 1
rect1.y += 1
self.button1.SetRect(rect1)
rect2 = self.GetFieldRect(2)
rect2.x += 1
rect2.y += 1
self.button2.SetRect(rect2)
self.sizeChanged = False
class MainFrame(wx.Frame):
"""Constructor"""
def __init__(self, parent, id):
wx.Frame.__init__(self, None)
self.status_bar = MyStatusBar(self)
self.SetStatusBar(self.status_bar)
self.Refresh()
self.Show()
if __name__ == "__main__":
app = wx.App()
MainFrame(None, -1)
app.MainLoop()
最简单的方法是继承 wx.StatusBar 本身,添加按钮,然后捕获 wx.EVT_SIZE
。这样您就可以捕获调整大小事件并可以根据需要重新定位小部件。
wxPython 演示有一个示例,其中有一个复选框小部件,方法如下:
# reposition the checkbox
def Reposition(self):
rect = self.GetFieldRect(1)
rect.x += 1
rect.y += 1
self.cb.SetRect(rect)
self.sizeChanged = False
self.GetFieldRect(1)
指的是复选框小部件。您可以使用类似这样的东西,但您需要跟踪两个小部件的位置并相应地更新。