Search code examples
pythonwxpythonwxwidgets

How to use Refresh with a wx.ColourDialog in wxpython?


i am trying to Refresh() a panel which uses the wx.ColourDialog. Once I refresh the panel once, it is unable to refresh again. Try the following to see the problem in action.

By clicking the button, it will ask you what color you would like to change the rectangle to. Once you press OK, it should change the rectangles color. It will not work it will not change the rectangle.

import wx 
xcolor_of_font_dia=(0,0,0)
class MyFrame(wx.Frame): 
    """a frame with a panel"""
    def __init__(self, parent=None, id=wx.ID_ANY, title=None):
        global xcolor_of_font_dia
        global dc
        wx.Frame.__init__(self, parent, wx.ID_ANY, title) 
        self.panel = wx.Panel(self, size=(350, 200)) 
        self.panel.Bind(wx.EVT_PAINT, self.on_paint)
        self.button2 = wx.Button(self.panel, id=wx.ID_ANY, label='Button2',pos=(8, 38), size=(175, 28))
        self.button2.Bind(wx.EVT_BUTTON, self.onColorDlg)
        self.Fit() 
    def onColorDlg(self, event):
        global xcolor_of_font_dia
        global dc
        """
        This is mostly from the wxPython Demo!
        """
        dlg = wx.ColourDialog(self)

        # Ensure the full colour dialog is displayed, 
        # not the abbreviated version.
        dlg.GetColourData().SetChooseFull(True)

        if dlg.ShowModal() == wx.ID_OK:
            data = dlg.GetColourData()
            print 'You selected: %s\n' % str(data.GetColour().Get())
            xcolor_of_font_dia='#%02x%02x%02x' % data.GetColour().Get()
        dlg.Destroy()
        self.panel.Refresh()
    def on_paint(self, event):
        global xcolor_of_font_dia
        global dc
        dc = wx.PaintDC(self.panel)
        dc.SetPen(wx.Pen(xcolor_of_font_dia, 1))
        rect = wx.Rect(50, 50, 100, 100) 
        dc.DrawRoundedRectangleRect(rect, 8)


# test it ...
app = wx.PySimpleApp() 
frame1 = MyFrame(title='rounded-rectangle & circle') 
frame1.Center() 
frame1.Show() 
app.MainLoop()

Solution

  • I cleaned your code a bit. Basically your globals were producing some problems as you were creating (and deleting) different dc instances after every size event.
    You should not use globals if it is not strictly necessary (rarely is).

    This works:

    import wx 
    
    
    class MyFrame(wx.Frame): 
        """a frame with a panel"""
        def __init__(self, parent=None, id=wx.ID_ANY, title=None):
            wx.Frame.__init__(self, parent, wx.ID_ANY, title) 
            self.xcolor = (0, 0, 0)
            self.panel = wx.Panel(self, size=(350, 200)) 
            self.panel.Bind(wx.EVT_PAINT, self.on_paint)
            self.button2 = wx.Button(self.panel, id=wx.ID_ANY, label='Button2',
                                                 pos=(8, 38), size=(175, 28))
            self.button2.Bind(wx.EVT_BUTTON, self.onColorDlg)
    
            self.Fit() 
    
        def onColorDlg(self, event):
            """
            This is mostly from the wxPython Demo!
            """
            dlg = wx.ColourDialog(None)
            dlg.GetColourData().SetChooseFull(True)
    
            if dlg.ShowModal() == wx.ID_OK:
                data = dlg.GetColourData()
                self.xcolor = data.GetColour().Get()
                print 'You selected: %s\n' % str(self.xcolor)
    
            dlg.Destroy()
            self.panel.Refresh()
    
        def on_paint(self, event):
            dc = wx.PaintDC(self.panel)
            dc.SetPen(wx.Pen(self.xcolor, 2))
            rect = wx.Rect(50, 50, 100, 100) 
            dc.DrawRoundedRectangleRect(rect, 8)
    
    
    # test it ...
    app = wx.PySimpleApp() 
    frame1 = MyFrame(title='rounded-rectangle & circle') 
    frame1.Center() 
    frame1.Show() 
    app.MainLoop()