wx.ListCtrl Bilder einlesen und anzeigen

Plattformunabhängige GUIs mit wxWidgets.
Antworten
bastep
User
Beiträge: 4
Registriert: Samstag 23. April 2016, 22:49

Hallo und gute Abend.
Problem: Ich will die Bilder eines Ordners auslesen und in einem ListCtrl anzeigen lassen. Die Darstellung der Bilder im ListCtrl untereinander habe ich hinbekommen. Aber mit dem Darstellen der Bilder nebeneinander habe ich erhebliche Probleme. Der nachfolgende Quelltext läuft, aber ich bekomme keine Bilder angezeigt. Eine suche mit Google hat nur ein paar veraltete Beispiele hervorgezaubert, die aber syntaktisch nicht mehr stimmen. An der Farbraum Meldung kann es nicht liegen, weil wie gesagt die Bilder untereinander darzustellen einwandfrei funktioniert.

Hat jemand eine Ahnung woran es liegen könnte?

Mit Dank im voraus
Stephan Bayer

Code: Alles auswählen

import wx
import os
from PIL import Image

#----------------------------------------------------------------------------------
# 
#----------------------------------------------------------------------------------
class ImageListCtrl(wx.ListCtrl):
    def __init__(self, parent):
        wx.ListCtrl.__init__(self, parent, style=wx.LC_ICON)
        
        self.List = wx.ImageList(24, 24)
        self.SetImageList(self.List, wx.IMAGE_LIST_SMALL)

    #----------------------------------------------------------------------------------
    # Konvertieung ist notwendig da einige Bilder
    # probleme mit dem Farbraum haben.
    # iCCP: known incorrect sRGB profile
    #----------------------------------------------------------------------------------
    def convertImage(self, fileName):
        try:
            with Image.open(fileName) as img:
                img = img.convert('RGB')
                image = wx.Image(img.size[0], img.size[1], img.tobytes())
                image = image.Scale(24, 24)
                return (True, wx.Bitmap(image))
        except OSError:
            return (False, None)

    #----------------------------------------------------------------------------------
    def addImages(self, imageDir):
        fileList = os.listdir(imageDir)
        for fileName in fileList:
            if fileName.endswith('.jpg') or fileName.endswith('.png'):
                (ok, image) = self.convertImage("{}\{}".format(imageDir, fileName))
                if ok:
                    browserimg = self.List.Add(image)
                    i = self.InsertItem(browserimg, 0)
                    #self.SetItem(i, 1, fileName)
                    self.SetItemImage(i, browserimg)

#----------------------------------------------------------------------------------
# 
#----------------------------------------------------------------------------------
class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title='Bilder aus Ordner anzeigen')
        
        panel = wx.Panel(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.imageListCtrl = ImageListCtrl(panel)
        sizer.Add(self.imageListCtrl, 1, wx.ALL|wx.EXPAND, 5)
        self.imageListCtrl.addImages(r'D:\Poser 11 Content\03 La Femme\Runtime\Textures\RPublishing\LaFemme')
        panel.SetSizer(sizer)
        self.Show()

app = wx.App()
frame = MainFrame()
app.MainLoop()

Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Kommentare sollten einen Mehrwert haben, also beschreiben, warum etwas gemacht wird, Kommentare die nur aus Minuszeichen bestehen, sind ziemlich wertlos.
Pfade setzt man nicht per Stringformatierungs zusammen, und os.listdir ist veraltet. Statt dessen benutzt man pathlib.
Um Fehler zu melden, gibt es Exceptions. Notfalls noch ein Rückgabewert von None, aber niemals benutzt man ein zusätzliches Flag, um Fehler weiterzumelden.
Es fehlt die main-Funktion.
Wenn Du eine IMAGE_LIST_SMALL hast, dann sollte das List-Control auch SMALL_ICON darstellen.

Code: Alles auswählen

import wx
from pathlib import Path
from PIL import Image

IMAGE_PATH = Path('D:/Poser 11 Content/03 La Femme/Runtime/Textures/RPublishing/LaFemme')

class ImageListCtrl(wx.ListCtrl):
    def __init__(self, parent):
        wx.ListCtrl.__init__(self, parent, style=wx.LC_SMALL_ICON)
        self.imagelist = wx.ImageList(24, 24)
        self.SetImageList(self.imagelist, wx.IMAGE_LIST_SMALL)

    def convertImage(self, filename):
        # Konvertieung ist notwendig da einige Bilder
        # probleme mit dem Farbraum haben.
        # iCCP: known incorrect sRGB profile
        with Image.open(str(filename)) as img:
            img = img.convert('RGB')
            image = wx.Image(img.size[0], img.size[1], img.tobytes())
            image = image.Scale(24, 24)
            return wx.Bitmap(image)

    def addImages(self, image_path):
        for extension in ['*.jpg', '*.png']:
            for path in image_path.glob(extension):
                try:
                    image = self.convertImage(path)
                except OSError:
                    # ignore not loadable images
                    pass
                else:
                    icon_index = self.imagelist.Add(image)
                    index = self.InsertItem(icon_index, 0)
                    self.SetItem(index, 0, path.name)
                    self.SetItemImage(index, icon_index)


class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title='Bilder aus Ordner anzeigen')
        panel = wx.Panel(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.imagelist_control = ImageListCtrl(panel)
        sizer.Add(self.imagelist_control, 1, wx.ALL|wx.EXPAND, 5)
        self.imagelist_control.addImages(IMAGE_PATH)
        panel.SetSizer(sizer)
        self.Show()

def main():
    app = wx.App()
    frame = MainFrame()
    app.MainLoop()

if __name__ == "__main__":
    main()
bastep
User
Beiträge: 4
Registriert: Samstag 23. April 2016, 22:49

Danke für die Anmerkungen und Hinweise zu meinem Code. Nach ein paar kleinen Änderungen im neuen Code werden die Bilder jetzt neben und untereinander angezeigt. Änderungen habe ich markiert.
Danke und gute Nacht
Mit freundlichen Grüßen

Code: Alles auswählen

import wx
from pathlib import Path
from PIL import Image

IMAGE_PATH = Path('D:/Poser 11 Content/03 La Femme/Runtime/Textures/RPublishing/LaFemme')

class ImageListCtrl(wx.ListCtrl):
    def __init__(self, parent, style):
        wx.ListCtrl.__init__(self, parent, style=style) # geaendert
        self.imagelist = wx.ImageList(24, 24)
        self.SetImageList(self.imagelist, wx.IMAGE_LIST_NORMAL) # geaendert

    def convertImage(self, filename):
        # Konvertieung ist notwendig da einige Bilder
        # probleme mit dem Farbraum haben.
        # iCCP: known incorrect sRGB profile
        with Image.open(str(filename)) as img:
            img = img.convert('RGB')
            image = wx.Image(img.size[0], img.size[1], img.tobytes())
            image = image.Scale(24, 24)
            return wx.Bitmap(image)

    def addImages(self, image_path):
        for extension in ['*.jpg', '*.png']:
            for path in image_path.glob(extension):
                try:
                    image = self.convertImage(path)
                except OSError:
                    # ignore not loadable images
                    pass
                else:
                    icon_index = self.imagelist.Add(image)
                    index = self.InsertItem(icon_index, 0)
                    #self.SetItem(i, 1, fileName) ---- war mit absicht auskommentiert
                    self.SetItemImage(index, icon_index)

class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title='Bilder aus Ordner anzeigen')
        panel = wx.Panel(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.imagelist_control = ImageListCtrl(panel, wx.LC_ICON|wx.LC_AUTOARRANGE) # geaendert
        sizer.Add(self.imagelist_control, 1, wx.ALL|wx.EXPAND, 5)
        self.imagelist_control.addImages(IMAGE_PATH)
        panel.SetSizer(sizer)
        self.Show()

def main():
    app = wx.App()
    frame = MainFrame()
    app.MainLoop()

if __name__ == "__main__":
    main()
Antworten