I have tried to run this on CentOS 7 (python 3.6, wxpython4) and Rocky 9 (python 3.9, wxpython4) with no luck. Am I missing a setting? Is it a theme issue?
Passing the required size to the Gauge constructor seems to work for me, using wxPython 4.2.3 gtk3 (phoenix) wxWidgets 3.2.7 + Python 3.12.3 + Linux Mint 22.1
EDIT: the reason I ask is that I found an issue raised on the wxWidgets repository that looks like it is related:
A fix for that issue was included in wxWidgets 3.2.5 which was released on 13th May 2024. The first version of wxPython that included the fix was 4.2.2 which was released 11th November 2024.
I started with my basic example to show the problem. Well, my actual implementation is a vertical gauge and it looks like vertical mode is not implemented for PyGauge, lol
I found an old thread on Stack Overflow which refers to vertical not being supported. The OP posted a snippet of code which acts as workaround.
I tried to incorporate that snippet in a class derived from PyGauge, by overriding its OnPaint() method. It only works in solid colour mode (not gradient mode) and text values may be in the wrong position (not tested).
When the example below is run the gauge grows from the top to the bottom, so you may need to change that.
import copy
import wx
import wx.lib.agw.pygauge as PG
class CustomPyGauge(PG.PyGauge):
def OnPaint(self, event):
"""
Handles the ``wx.EVT_PAINT`` event for :class:`PyGauge`.
:param `event`: a :class:`PaintEvent` event to be processed.
"""
dc = wx.BufferedPaintDC(self)
rect = self.GetClientRect()
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
dc.Clear()
colour = self.GetBackgroundColour()
dc.SetBrush(wx.Brush(colour))
dc.SetPen(wx.Pen(colour))
dc.DrawRectangle(rect)
if self._border_colour:
dc.SetPen(wx.Pen(self.GetBorderColour()))
dc.DrawRectangle(rect)
pad = 1 + self.GetBorderPadding()
rect.Deflate(pad,pad)
if self.GetBarGradient():
for i, gradient in enumerate(self._barGradientSorted):
c1,c2 = gradient
w = rect.width * (float(self._valueSorted[i]) / self._range)
r = wx.Rect(rect)
r.width = int(w)
dc.GradientFillLinear(r, c1, c2, wx.EAST)
else:
for i, colour in enumerate(self._barColourSorted):
dc.SetBrush(wx.Brush(colour))
dc.SetPen(wx.Pen(colour))
r = copy.copy(rect)
if self.WindowStyle & wx.GA_VERTICAL:
h = rect.height * (float(self._valueSorted[i]) / self._range)
r.height = int(h)
else:
w = rect.width * (float(self._valueSorted[i]) / self._range)
r.width = int(w)
dc.DrawRectangle(r)
if self._drawIndicatorText:
dc.SetFont(self._drawIndicatorText_font)
dc.SetTextForeground(self._drawIndicatorText_colour)
drawValue = self._valueSorted[i]
if self._drawIndicatorText_drawPercent:
drawValue = (float(self._valueSorted[i]) * 100) / self._range
drawString = self._drawIndicatorText_formatString.format(
drawValue, value=drawValue, range=self._range)
rect = self.GetClientRect()
(textWidth, textHeight, descent, extraLeading) = dc.GetFullTextExtent(drawString)
textYPos = (rect.height-textHeight)//2
if textHeight > rect.height:
textYPos = 0-descent+extraLeading
textXPos = (rect.width-textWidth)//2
if textWidth>rect.width:
textXPos = 0
dc.DrawText(drawString, textXPos, textYPos)
class GaugeFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'Gauge Example', size=(150, 500))
panel = wx.Panel(self, -1)
self.count = 0
self.gauge = CustomPyGauge(panel, -1, size=(100, 300), style=wx.GA_VERTICAL)
self.gauge.SetBackgroundColour('light green')
self.gauge.SetBorderColor(wx.BLACK)
self.gauge.SetRange(50)
self.gauge.SetValue(0)
self.timer = wx.Timer(self)
self.timer.Start(100)
self.Bind(wx.EVT_TIMER, self.TimerHandler)
def __del__(self):
self.timer.Stop()
def TimerHandler(self, event):
self.count = self.count+1
if self.count == 50:
self.timer.Stop()
self.gauge.SetValue(self.count)
self.gauge.Refresh()
app = wx.App()
GaugeFrame().Show()
app.MainLoop()