Phoenix icon indicating copy to clipboard operation
Phoenix copied to clipboard

Problem with wx.ProgressDialog

Open komoto48g opened this issue 2 years ago • 3 comments

Operating system: Windows 10 wxPython version & source: wxPython 4.1.2a1.dev5434+7d45ee6a (whl) Python version & source: 3.10.4

Description of the problem: The Wx.ProgressDialog has a default argument parent=None. (https://docs.wxpython.org/wx.ProgressDialog.html#wx.ProgressDialog.init)

The table below shows dialog modes for parent None or self (!=None) and style PD_APP_MODAL or PD_AUTO_HIDE (!=PD_APP_MODAL). There is no problem when parent=self but there are two problems when parent=None indicated by (*1)(*2).

parent=None parent=self
style=PD_APP_MODAL A (*1) A
style=PD_AUTO_HIDE A (*2) B

A. modal to all windows
B. modal to the parent window (*1) a bug: "going to background"; When the progress dialog ends, it goes behind the command prompt. (*2) a bug: "imperfect modal mode"; When you move focus to another window while progressing, it will freeze keyboard input, then crash the program.

Code Example (click to expand)
import sys
import time
import wx

print("Python {}".format(sys.version))
print("wxPython {}".format(wx.version()))

class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        txt = wx.TextCtrl(self)
        btn = wx.Button(self, label="Test")
        btn.Bind(wx.EVT_BUTTON, lambda v: self.test())
        
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.AddMany([
            (btn, 0, wx.EXPAND | wx.ALL, 0),
            (txt, 1, wx.EXPAND | wx.ALL, 0),
        ])
        self.SetSizer(sizer)
        self.Show()

    def test(self):
        with wx.ProgressDialog(
                "Update",
                "Updating... {}".format(self.Title),
                ## style=wx.PD_APP_MODAL|wx.PD_AUTO_HIDE, #(default)
                style=wx.PD_AUTO_HIDE,
                ## parent=self,
                maximum=100) as dlg:
            for i in range (100):
                dlg.Update(i+1)
                time.sleep(0.05)
                #wx.GetApp().Yield() # (*) without this, it will freeze keyboard input...

if __name__ == "__main__":
    app = wx.App()
    frm = Frame(None, title="frame")
    frm2 = Frame(None, title="frame2")
    app.MainLoop()

EDIT I will put the video clips later.

https://user-images.githubusercontent.com/83063554/175100060-b165bc36-fdf5-4d95-81b0-246f1e2c66de.mp4

https://user-images.githubusercontent.com/83063554/175100076-9bdeb942-aace-4678-95fb-eac0c3a12183.mp4

komoto48g avatar Jun 21 '22 16:06 komoto48g

This issue has been mentioned on Discuss wxPython. There might be relevant details there:

https://discuss.wxpython.org/t/wxpython-app-frame-goes-to-background-after-progressdialog-is-closed/36022/22

RobinD42 avatar Jun 21 '22 17:06 RobinD42

As written on discuss... I see the "going to background" behaviour also with pure wxWidgets.

DietmarSchwertberger avatar Jun 23 '22 16:06 DietmarSchwertberger

This issue has been mentioned on Discuss wxPython. There might be relevant details there:

https://discuss.wxpython.org/t/progressdialog-pulse-help-again/36614/4

RobinD42 avatar Aug 20 '23 07:08 RobinD42