I want to achieve a status bar with 2 fields. The first one left-aligned and the second one right-aligned. Illustration of what I want:
| | | | ================================================================================= | Some status text. v. 1.0.32 |
My current code:
self.CreateStatusBar(2)
self.SetStatusWidths([-1, -1])
But the right field is left aligned, so it looks like this:
| | | | ================================================================================= | Some status text. v. 1.0.32 |
Is there any way to get text in the right field to align to the right?
Ok, I've solved the problem (even though it feels like a hack.) I created a custom toolbar that defines two fields. The left field can be controlled like normal, and the right field contains a StaticText
control, containing the version number, that is manually positioned. The code for positioning the text is platform specific since it looked a tad different on windows. Here are some screenshots:
Windows 7:
OSX 10.8.1 Mountain Lion:
Here is the code for the custom status bar:
class CustomStatusBar(wx.StatusBar):
"""A custom status bar for displaying the application version in the bottom
right corner."""
def __init__(self, parent):
wx.StatusBar.__init__(self, parent, -1)
self.SetFieldsCount(2)
self.SetStatusWidths([-1, -1])
# Set up the version label.
self.version_label = wx.StaticText(self, -1, 'Version: ' + VERSION)
self.reposition_version_label()
# Listen to the resize event.
self.Bind(wx.EVT_SIZE, self.on_resize)
def on_resize(self, event):
self.reposition_version_label()
def reposition_version_label(self):
# Get the rect of the second field.
field_rect = self.GetFieldRect(1)
label_rect = self.version_label.GetRect()
# Reduce the width of the field rect to the width of the label rect and
# increase it's x value by the same about. This will result in it being
# right aligned.
width_diff = field_rect.width - label_rect.width
field_rect.width = label_rect.width
field_rect.x += width_diff
# On windows, the text is a little too high up, so increase the Y value
# a little.
if sys.platform == 'win32':
field_rect.y += 3
# Set the resulting rect to the label.
self.version_label.SetRect(field_rect)
This code is in my Frame
's constructor to create and place the status bar:
self.statusbar = CustomStatusBar(self)
self.SetStatusBar(self.statusbar)
And I added this function to my frame for easy status updates:
def set_status_text(text):
self.statusbar.SetStatusText(text, 0)
I hope this helps somebody else down the line.
The hacky version wasn't exactly ideal for what I was looking for. I found setting static width size based on the pixel size of the string worked great for me. Adapted to the environment nicely and can be changed dynamically. This was done with Python 3 and wxPython Phoenix, so maybe this method wasn't available before.
Here is a simple version.
import wx
class MainWindow(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent)
version = "v. 1.0.32 (2012-11-03)"
# Returns a Size object of the pixel dimensions of a string
version_size = wx.Window.GetTextExtent(self, version)
# Create a status bar with two sections
self.CreateStatusBar(2)
# Set the left side to a negative number indicating it's fluid width
# The right side will be the exact size of the version string
self.SetStatusWidths([-1, version_size.width])
# Set the left side of the status bar to some text. 0 is first section
self.SetStatusText("left status bar text", 0)
# Set right side to version number. 1 is second section
self.SetStatusText(version, 1)
self.Show()
app = wx.App()
frame = MainWindow(None)
app.MainLoop()
To show how it can be updated dynamically here is a bit more complex version with threaded random updates.
import wx
import time
import random
import threading
class MainWindow(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent)
version = "v. 1.0.32 (2012-11-03)"
# Returns a Size object of the pixel dimensions of a string
version_size = wx.Window.GetTextExtent(self, version)
# Create a status bar with two section
self.CreateStatusBar(2)
# Set the left side to a negative number indicating it's fluid width
# The right side will be the exact size of the version string
self.SetStatusWidths([-1, version_size.width])
# Set the left side of the status bar to some text. 0 is first section
self.SetStatusText("left status bar text", 0)
# Set right side to version number. 1 is second section
self.SetStatusText(version, 1)
self.Show()
# Thread to update status bar with causing the GUI to hang
run_version_updates = threading.Thread(target=self.thread_version_updating)
run_version_updates.start()
def thread_version_updating(self):
for i in range(10):
time.sleep(1)
# Create a random string of 1-20 characters containing only "ABC123"
random_string = "".join(random.choice("ABC123") for _ in range(random.randrange(1,20)))
self.update_version(random_string)
def update_version(self, version):
# Get width of string, set status bar width, then update the text
size = wx.Window.GetTextExtent(self, version)
self.SetStatusWidths([-1, size.width])
self.SetStatusText(version, 1)
app = wx.App()
frame = MainWindow(None)
app.MainLoop()
I only have the one operating system, but here is what it looked like with different Windows 7 themes.
Win 7 Aero
Win 7 classic
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With