0

Hey everyone so I have an issue and not too sure how to go about it. I have some bitmaps that are produced depending on a query, the problem here is that once the query gets a little bigger my application uses all 10,000 GDI objects that's allowed for windows then it crashes . I'm not too familiar w/ GDI resources but maybe theres a way to fix this. Below are the snippets of the code that fails

legend file

def _init_ui(self):
    """Initialize UI components."""
    # Add layout management
    self.hbox = wx.BoxSizer(wx.HORIZONTAL)
    self.fgs = wx.FlexGridSizer(rows=self.n_items, cols=2, vgap=0, hgap=0)

    # Create items to add
    for _i, (key, value) in enumerate(zip(self.labels, self.colors)):
        self.label = wx.StaticText(self,
                                   label=str(key),
                                   style=wx.ALIGN_LEFT,
                                   )

        self.colorbox = csel.ColourSelect(self,
                                          _i,
                                          "",
                                          tuple(value),
                                          style=wx.NO_BORDER,
                                          size=(20, 20 ))

        self.Bind(csel.EVT_COLOURSELECT, self.on_color_pick, id=_i)

        self.fgs.Add(self.label, flag=wx.ALIGN_CENTER_VERTICAL)
        self.fgs.Add(self.colorbox)

    # Add our items to the layout manager and set the sizer.
    self.hbox.Add(self.fgs)
    self.SetSizer(self.hbox)

and it fails at the line size(20,20) this file then calls my colourselect file

def __init__(self, parent, id=wx.ID_ANY, label="", colour=wx.BLACK,
             pos=wx.DefaultPosition, size=wx.DefaultSize,
             callback=None, style=0):


    size = wx.Size(*size)
    if label:
        mdc = wx.MemoryDC(wx.Bitmap(1,1))
        w, h = mdc.GetTextExtent(label)
        w += 8
        h += 8
    else:
        w, h = 22, 22

    size.width = size.width if size.width != -1 else w
    size.height = size.height if size.height != -1 else h
    super(ColourSelect, self).__init__(parent, id, wx.Bitmap(w,h,32),
                             pos=pos, size=size, style=style,
                             name='ColourSelect')

    if type(colour) == type( () ):
        colour = wx.Colour(*colour)

    self.colour = colour
    self.SetLabel(label)
    self.callback = callback
    bmp = self.MakeBitmap()
    self.SetBitmap(bmp)
    self.customColours = None
    parent.Bind(wx.EVT_BUTTON, self.OnClick, self)

this fails at the call self.SetBipMap(bmp)

which calls this small function in the same file

def SetBitmap(self, bmp):
    """
    Sets the bitmap representation of the current selected colour to the button.

    :param wx.Bitmap `bmp`: the new bitmap.
    """

    self.SetBitmapLabel(bmp)
    self.Refresh()

and lastly is trace back to this last function in my file called buttons

def SetBitmapLabel(self, bitmap, createOthers=True):

    self.bmpLabel = bitmap
    if bitmap is not None and createOthers:
        image = bitmap.ConvertToImage()
        imageutils.grayOut(image)
        self.SetBitmapDisabled(wx.Bitmap(image))

and the fail happens at **image = bitmap.ConvertToImage() ** if anyone can suggest any changes to help optimize my program I would really appreciate it. A lot of the code is from other libraries that are imported so i'm not really familiar with parts of it. Hopefully someone has an idea

VZ.
  • 21,740
  • 3
  • 39
  • 42
Jeff Pernia
  • 79
  • 1
  • 13
  • Trying to have and display 10000 items at once is not a good GUI design. You better select and work with those who are really displayed. For example you could have an array of really-to-show-now controls and draw only them at the paint-event of that window. Or if the controls are similar just fill with right data the ones that are currently seen. – Ripi2 Oct 31 '18 at 17:44
  • It's an old reference but see: https://stackoverflow.com/questions/9723470/whats-the-upper-limit-on-gdi-objects-for-one-process-in-windows-7 – Rolf of Saxony Oct 31 '18 at 18:01
  • @Ripi2 like I said these libraries are imported so im not too sure what part is actually painting them and also i'm not sure if your comment has a lot of typos but im having issues understanding what you're saying – Jeff Pernia Oct 31 '18 at 21:02
  • It seems to me that in that `for` loop you're creating 10000 controls and adding them to a `wxSizer`. Then you rely on sizer and OS to display them correctly. I'm taking about deciding first which controls are visible and later create them and add to the sizer. Another way is re-using an old control with new data. – Ripi2 Nov 01 '18 at 20:31

0 Answers0