Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wx.lib.agw.pygauge: not automatically refreshing after SetValue, like wx.gauge does #2699

Open
arigit opened this issue Feb 9, 2025 · 2 comments

Comments

@arigit
Copy link
Contributor

arigit commented Feb 9, 2025

wx.lib.agw.pygauge: does not automatically Refresh() after SetValue, like wx.gauge does.

wx.lib.agw.pygauge does automatically refresh after Update(increment, time) so the behavior is not consistent even within the widget.

Further, during initialization of lib.agw.pygauge (initial widget setup), if SetValue was called, then the value will be displayed appropriately. The behavior breaks for all subsequent calls to SetValue.

There are use-cases where SetValue is needed when using agw PyGauge, prior to using Update.

I built a short demo script to show the problem.

Request: please make wx.lib.agw.pygauge self-Refresh() after a call to SetValue. I found several discussions about this inconsistency during the last decade or so but it doesn't seem that a bug got ever opened for this.

import wx
import wx.lib.agw.pygauge as PG
import wx.lib.inspection


class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(
            None, title="wxPython agw.pygauge SetValue issue", size=(720, 600)
        )

        # Main panel
        panel = wx.Panel(self)

        # Vertical BoxSizer
        vbox = wx.BoxSizer(wx.VERTICAL)

        # Horizontal BoxSizer inside the VBox
        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        self.gauge_agw_pygauge = PG.PyGauge(
            panel, -1, size=(500, 50), style=wx.GA_HORIZONTAL
        )
        self.gauge_agw_pygauge.SetValue(15)
        self.gauge_agw_pygauge.SetDrawValue(
            draw=True,
            drawPercent=True,
            font=None,
            colour=wx.BLACK,
            formatString="agw.pygauge Processing  ({:.0f}%)",
        )
        self.gauge_agw_pygauge.SetBackgroundColour(wx.WHITE)
        self.gauge_agw_pygauge.SetBorderColor(wx.BLACK)
        hbox1.Add(self.gauge_agw_pygauge, flag=wx.ALL, border=10)

        hbox1_1 = wx.BoxSizer(wx.HORIZONTAL)
        self.gauge_wx_gauge = wx.Gauge(
            panel, range=100, size=(500, 50), style=wx.GA_HORIZONTAL
        )
        self.gauge_wx_gauge.SetValue(15)
        hbox1_1.Add(self.gauge_wx_gauge, flag=wx.ALL, border=10)

        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        self.button_set_value_wxgauge_no_refresh = wx.Button(
            panel, label="wx.gauge: Set Value to 50 without Refresh - Works"
        )
        self.Bind(
            wx.EVT_BUTTON,
            self.onclick_button_set_value_wxgauge_no_refresh,
            self.button_set_value_wxgauge_no_refresh,
        )
        hbox2.Add(
            self.button_set_value_wxgauge_no_refresh,
            flag=wx.ALIGN_CENTER | wx.ALL,
            border=20,
        )

        hbox2_1 = wx.BoxSizer(wx.HORIZONTAL)
        self.button_set_value_agw_no_refresh = wx.Button(
            panel, label="agw.pygauge: Set Value to 50 without Refresh - FAILS"
        )
        self.Bind(
            wx.EVT_BUTTON,
            self.onclick_button_set_value_agw_no_refresh,
            self.button_set_value_agw_no_refresh,
        )
        hbox2_1.Add(
            self.button_set_value_agw_no_refresh,
            flag=wx.ALIGN_CENTER | wx.ALL,
            border=20,
        )

        hbox2_2 = wx.BoxSizer(wx.HORIZONTAL)
        self.button_set_value_agw_with_refresh = wx.Button(
            panel, label="agw.pygauge: Set Value to 50 with Refresh - Works"
        )
        self.Bind(
            wx.EVT_BUTTON,
            self.onclick_button_set_value_agw_with_refresh,
            self.button_set_value_agw_with_refresh,
        )
        hbox2_2.Add(
            self.button_set_value_agw_with_refresh,
            flag=wx.ALIGN_CENTER | wx.ALL,
            border=20,
        )

        hbox3 = wx.BoxSizer(wx.HORIZONTAL)
        self.button_set_value_agw_hack = wx.Button(
            panel,
            label="agw.pygauge hack: Set Value to 50 - hack: set to 49 and then call .Update(1,1)",
        )
        self.Bind(
            wx.EVT_BUTTON,
            self.onclick_button_set_value_agw_hack,
            self.button_set_value_agw_hack,
        )
        hbox3.Add(
            self.button_set_value_agw_hack, flag=wx.ALIGN_CENTER | wx.ALL, border=20
        )

        self.reset_gauge_timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.on_reset_gauge_timer_finished, self.reset_gauge_timer)

        # Add HBox to VBox
        vbox.Add(hbox1, flag=wx.ALIGN_CENTER)
        vbox.Add(hbox1_1, flag=wx.ALIGN_CENTER)
        vbox.Add(hbox2, flag=wx.ALIGN_CENTER)
        vbox.Add(hbox2_1, flag=wx.ALIGN_CENTER)
        vbox.Add(hbox2_2, flag=wx.ALIGN_CENTER)
        vbox.Add(hbox3, flag=wx.ALIGN_CENTER)

        # Set sizer for the panel
        panel.SetSizer(vbox)

        self.Centre()

    def on_reset_gauge_timer_finished(self, e):
        self.gauge_wx_gauge.SetValue(15)
        self.gauge_agw_pygauge.SetValue(15)
        self.gauge_agw_pygauge.Refresh()

    def onclick_button_set_value_wxgauge_no_refresh(self, e):
        self.gauge_wx_gauge.SetValue(50)
        self.reset_gauge_timer.Start(2000)

    def onclick_button_set_value_agw_no_refresh(self, e):
        self.gauge_agw_pygauge.SetValue(50)
        self.reset_gauge_timer.Start(2000)

    def onclick_button_set_value_agw_with_refresh(self, e):
        self.gauge_agw_pygauge.SetValue(50)
        self.gauge_agw_pygauge.Refresh()
        self.reset_gauge_timer.Start(2000)

    def onclick_button_set_value_agw_hack(self, e):
        self.gauge_agw_pygauge.SetValue(49)
        self.gauge_agw_pygauge.Update(1, 1)  # add 1 more in 1 ms to get 50
        self.reset_gauge_timer.Start(2000)


if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame()
    frame.Show()
    # wx.lib.inspection.InspectionTool().Show()
    app.MainLoop()
@swt2c
Copy link
Collaborator

swt2c commented Feb 9, 2025

Is it enough to add a self.Refresh() at the end of SetValue()?

Update: seems to work with your test case.

@arigit
Copy link
Contributor Author

arigit commented Feb 10, 2025

do you mean in the definition of SetValue of wx.lib.agw.pygauge? if so - yes it would totally do.

This is for new users like me that got stuck with this behavior, having a consistent auto-refresh that behaves like in wx.gauge would have saved quite some time trying to understand why the widget was not updating.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants