why is my text not aligning properly in wxPython?

2024/9/21 12:27:35

I'm using wxPython to build a GUI and I'm trying to align some text but it's not working at all. I'm trying align three different static text items in three places (right aligned, center aligned, and left aligned) in three seperate panels. The result that I'm getting though is that all three static text controls are aligned in the top left corners of their respective panels. text not aligned

This is code I have:

    self.lastText=wx.StaticText(self.textDisplayPanel1, label=self.lastWords, style=wx.ALIGN_RIGHT)self.currentText=wx.StaticText(self.textDisplayPanel2, label=self.currentWords, style=wx.ALIGN_CENTRE)self.nextText=wx.StaticText(self.textDisplayPanel3, label=self.nextWords, style=wx.ALIGN_LEFT)

Any ideas on how I fix this?

Thank you!

I'm running mac OSX 10.7.2 with Python 2.7.1 and wxPython 2.8.12.1

Answer

Edit: Although everything commented below works on windows, the first option would not work on, for example, Ubuntu due to maybe a bug. A previous post given in the comments indicate that the same problem is found in OSX.
In any case, the second option using vertical sizers works both in Ubuntu and windows so you could try it on OSX.


Your text has the instruction to align in the way you want with wx.ALIGN... and, in fact, it is aligned. However the size of the StaticText is not that of the panel but just the size of the text. Having restricted its position to its own size, you can not see the diference between the alignment modes.

You have two options to solve the problem:

Option 1. Expand the StaticText widget size and position your text on it

You could expand the size of your StaticText widget using its size parameter. This is a bad solution except for fixed size parents or frames you are not going to change size or reuse in other applications. If the size of the widget containing the text changes then the relative position of the text will be also modified because its size stays fixed. So it is always better to organize your widgets by means of sizers.

The proportion of the available space the widget occupies in the sizer slot is given by the second parameter in sizer.Add() (0 is minimal size, 1 is full occupation):

sizer_2.Add(self.label_1, 0, 0, 0)

enter image description here

To see the text aligned in the panel as you want you have to tell the StaticText to expand to all the space available:

sizer_2.Add(self.label_1, 1, 0, 0)

enter image description here

Here you have the relevant code:

class MyFrame(wx.Frame):def __init__(self, *args, **kwds):wx.Frame.__init__(self, *args, **kwds)self.panel_1 = wx.Panel(self, -1)self.label_1 = wx.StaticText(self.panel_1, -1, "label_1", style=wx.ALIGN_RIGHT)self.panel_2 = wx.Panel(self, -1)self.label_2 = wx.StaticText(self.panel_2, -1, "label_2", style=wx.ALIGN_CENTRE)self.panel_3 = wx.Panel(self, -1)self.label_3 = wx.StaticText(self.panel_3, -1, "label_3")self.panel_1.SetBackgroundColour(wx.Colour(0, 255, 0))self.panel_2.SetBackgroundColour(wx.Colour(0, 255, 255))self.panel_3.SetBackgroundColour(wx.Colour(219, 112, 147))sizer_1 = wx.BoxSizer(wx.HORIZONTAL)sizer_2 = wx.BoxSizer(wx.HORIZONTAL)sizer_3 = wx.BoxSizer(wx.HORIZONTAL)sizer_4 = wx.BoxSizer(wx.HORIZONTAL)sizer_2.Add(self.label_1, 1, 0, 0)sizer_3.Add(self.label_2, 1, 0, 0)sizer_4.Add(self.label_3, 1, 0, 0)self.panel_1.SetSizer(sizer_2)self.panel_2.SetSizer(sizer_3)self.panel_3.SetSizer(sizer_4)sizer_1.Add(self.panel_1, 1, wx.EXPAND, 0)sizer_1.Add(self.panel_2, 1, wx.EXPAND, 0)sizer_1.Add(self.panel_3, 1, wx.EXPAND, 0)self.SetSizer(sizer_1)sizer_1.Fit(self)self.Layout()

enter image description here

Note the code is longer than needed in order to mimick your example with three panels. You obtain the same frame view using one only panel. In fact it could be simplified further not using panels and setting the StaticText directly on the sizer:

class MyFrame2(wx.Frame):def __init__(self, *args, **kwds):wx.Frame.__init__(self, *args, **kwds)self.label_1 = wx.StaticText(self, -1, "label_1", style=wx.ALIGN_RIGHT)self.label_2 = wx.StaticText(self, -1, "label_2", style=wx.ALIGN_CENTRE)self.label_3 = wx.StaticText(self, -1, "label_3")self.label_1.SetBackgroundColour(wx.Colour(127, 255, 0))self.label_2.SetBackgroundColour(wx.Colour(0, 255, 255))self.label_3.SetBackgroundColour(wx.Colour(219, 112, 147))sizer = wx.BoxSizer(wx.HORIZONTAL)sizer.Add(self.label_1, 1, wx.EXPAND, 0)sizer.Add(self.label_2, 1, wx.EXPAND, 0)sizer.Add(self.label_3, 1, wx.EXPAND, 0)self.SetSizer(sizer)sizer.Fit(self)self.Layout()

Option 2. Locate the widget itself in the desired position at the available space of the sizer. You could use the position parameter of StaticText for that purpose. But this would have the same problems indicated above for the use of size. So again you want to control the geometry of your views with sizers. You position the widget in the sizer using one of:

sizer_6.Add(self.label_5, 0, wx.ALIGN_RIGHT, 0)

or

sizer_7.Add(self.label_6, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)

For some reason, for this to work you need a vertical BoxSizer (and in the same way, if you would like to use wx.ALIGN_CENTER_VERTICAL you will need an horizontal BoxSizer:

class MyFrame(wx.Frame):def __init__(self, *args, **kwds):wx.Frame.__init__(self, *args, **kwds)self.panel_4 = wx.Panel(self, -1)self.label_5 = wx.StaticText(self.panel_4, -1, "label_5")self.panel_5 = wx.Panel(self, -1)self.label_6 = wx.StaticText(self.panel_5, -1, "label_6")self.panel_6 = wx.Panel(self, -1)self.label_7 = wx.StaticText(self.panel_6, -1, "label_7")self.panel_4.SetBackgroundColour(wx.Colour(0, 255, 255))self.panel_5.SetBackgroundColour(wx.Colour(127, 255, 0))self.panel_6.SetBackgroundColour(wx.Colour(219, 112, 219))sizer_1 = wx.BoxSizer(wx.HORIZONTAL)sizer_8 = wx.BoxSizer(wx.VERTICAL)sizer_7 = wx.BoxSizer(wx.VERTICAL)sizer_6 = wx.BoxSizer(wx.VERTICAL)sizer_6.Add(self.label_5, 0, wx.ALIGN_RIGHT, 0)sizer_7.Add(self.label_6, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)sizer_8.Add(self.label_7, 0, 0, 0)self.panel_4.SetSizer(sizer_6)self.panel_5.SetSizer(sizer_7)self.panel_6.SetSizer(sizer_8)sizer_1.Add(self.panel_4, 1, wx.EXPAND, 0)sizer_1.Add(self.panel_5, 1, wx.EXPAND, 0)sizer_1.Add(self.panel_6, 1, wx.EXPAND, 0)self.SetSizer(sizer_1)sizer_1.Fit(self)self.Layout()

This option implies a combination of panels and sizers that produces a code that is more difficult to simplify than that shown for the first option.

https://en.xdnf.cn/q/72062.html

Related Q&A

Python subprocess check_output decoding specials characters

Im having some issues with python encoding. When I try to execute this:subprocess.check_output("ipconfig", shell=True)it gives me an output with special characters in it, like:"Statut du…

Python - SystemError: NULL result without error in PyObject call

The story: Im trying to interface from C to Python in order to use the faster computational speed of C for an existing Python code. I already had some success, also with passing NumPy arrays - but now …

Fix jumping of multiple progress bars (tqdm) in python multiprocessing

I want to parallelize a task (progresser()) for a range of input parameters (L). The progress of each task should be monitored by an individual progress bar in the terminal. Im using the tqdm package f…

How to access data stored in QModelIndex

The code below create a single QListView with the data and proxy models "attached". Clicking one of the radio buttons calls for buttonClicked() function. This function calls models .data(inde…

Pythons read and write add \x00 to the file

I have come across a weird problem when working with files in python. Lets say I have a text file and a simple piece of code that reads the contents of the file and then rewrites it with unaltered cont…

NetworkX remove attributes from a specific node

I am having a problem with networkX library in python. I build a graph that initialises some nodes, edges with attributes. I also developed a method that will dynamic add a specific attribute with a sp…

How to use Python left outer join using FOR/LIST/DICTIONARY comprehensions (not SQL)?

I have two tuples, details below:t1 = [ [aa], [ff], [er] ]t2 = [ [aa, 11,], [er, 99,] ]and I would like to get results like these below using python method similar to SQLs LEFT OUTER JOIN:res = [ [aa, …

GaussianMixture initialization using component parameters - sklearn

I want to use sklearn.mixture.GaussianMixture to store a gaussian mixture model so that I can later use it to generate samples or a value at a sample point using score_samples method. Here is an exampl…

How to use geopy vicenty distance over dataframe columns?

I have a dataframe with location column which contains lat,long location as followsdeviceid location 1102ADb75 [12.9404578177, 77.5548244743]How to get the di…

Opening a postgres connection in psycopg2 causes python to crash

Im getting the following error message when I try to open up a connection to a postgres database. Perhaps its related to OpenSSL, but I cant understand the error message. Can anyone help?>>>…