Listbox mit Bildern?

Fragen zu Tkinter.
Antworten
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

Hi @ll,

ich hab mal wieder n seltsames Problem...

Ich möchte (am Liebsten mit Tkinter) eine Listbox erstellen. In diesem Fall sollen aber keine Texte, sondern Bilder eingefügt werden. Diese sollten dann, genau wie bei der typischen Listbox auswählbar sein etc.

Gibt es sowas überhaupt?


Falls es sowas nicht gibt:
Ich möchte ca. 200 (können auch mehr oder weniger Bilder) in einer Miniaturvorschau anzeigen lassen -- wie viele genau ist vor dem Start des Programms unbekannt --, dann soll man sich von diesen Bildern so viele aussuchen können, wie man will und dann sollen die Dateipfade übergeben werden.
Der Rest steht bereits.


Bisher habe ich es halt so gemacht, dass ich die Dateipfade in eine Listbox geschrieben hab und dann übern Event immer neben der Listbox dann eine Vorschau erzeugt habe. Habe nur festgestellt, dass man dann oftmals sehr umständlich die gewünschten Bilder suchen muss... -- mit einer Minivorschau für die Bilder wäre da meiner Meinung nach Abhilfe geschaffen...

Danke
Tux
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Hi Tux!
Tja, ich glaub, mit ner Listbox geht das nicht. Wie vor einiger Zeit schonmal in ähnlichem Zusammenhang erwähnt, musst du dir, wenn du deine "Perfektlösung" haben willst, was eigenes basteln. Entweder mit Tkinter.Canvas, oder mit Tix.ScolledFrame (heißt das so?). In Tkinter findet man immer was, was nicht vorgesehen ist, aber meistens kann man es auf etwas umständlichem Weg fast immer selber bauen. :wink:
Gruß, jj
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

Hi schlangenbeschwörer,

ich dachte mir ja schon sowas...

Hab mir jetzt mal Pmw (oder Pwm) angeschaut und hab ein ScrolledFrame gefunden. In der Theorie hab ich schon ne Idee es damit selbst zu basteln. Wäre halt nur einfacher gewesen, wenns sowas schon geben würde. Aber naja, dann gehts halt über doityourself...

Interessant zu wissen, dass Tix sowas auch hat. Mal sehn, welches mir besser gefällt...

Dank dir!

Grüßigkeiten
Tux
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Also wenn du nicht Tkinter, sondern wxPython verwenden willst kenne ich eine Lösung.

Hier habe ich den CustomTreeCtrl verwendet:
Bild

Falls du interessiert bist kann ich gerne auch den Code vom Tool posten.

Gruss
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Tux hat geschrieben: Interessant zu wissen, dass Tix sowas auch hat. Mal sehn, welches mir besser gefällt...
Oh, ich glaub ich meinte Pmw.ScrolledFrame. :lol:
Aber bei Tix könntest du dir vlt. mal tixCheckList angucken, ich kenn das aber auch nicht so gut. (Einfach mal kurz über die Tix-Widgetübersicht gucken.)
Gruß, jj
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

@schlangenbeschwörer:
Das Pwm.ScrolledFrame gefällt mir schonmal sehr gut - hab nur in der letzten Zeit das Proggen n bissl hinten anstellen müssen. Scheint aber für meine Zwecke gut geeignet zu sein.

@rayo:
Ich kenne mich mit wxPython nur sehr wenig aus. Kann man das CustomTreeCtrl auch gleich mit dem Explorer bündeln? GenereticWinDirCtrl oder sowas ähnliches hab ich schon mal gelesen?! Das wäre natürlich eine ausgezeichnete Variante - nur dass ich da wie gesagt noch nicht den so großen Durchblick hab. Könntest du mir da ggf. mal nen Quelltext schicken? eMailaddi wäre ich-aem@web.de
brauche ich irgendwelche bestimmten Module ausm Netz?

Riesiges Danke an euch beide!
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Willst du sowas wie eine Explorer Ansicht (unter Windows die Ansicht "Symbole") mit Icons? Also die Icons wären dann einfach Vorschaubilder.

Falsl du sowas suchst reicht dir aus wxPython sogar schon wx.ListCtrl.

Gruss
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

Ich versuch mal das, was ich brauche, im Wesentlichen zu beschreiben:
Irgendein Ordner auf der Festplatte soll ausgewählt werden. Alle Bilder in dem Ordner und den Unterordnern sollen als Vorschau dargestellt werden. Dann soll man, am Besten durch Checkbuttons, aussuchen können, welche Bilder man gern haben möchte. Über einen Button sollen dann alle ausgewählten Bilder bzw. deren Dateipfade an eine weitere Funktion übergeben werden.

@rayo: Ich weiß leider nicht zu 100% was du meinst. Wenn ich dich jetzt richtig verstanden habe, dann suche ich sowas - zumin. als Grundlage wäre es sicherlich sehr gut.
Ich müsste die Vorschaubilder halt noch auswählen können (müsste man ja mit nem Mausevent hinbekommen). Einen zusätzlichen Button für die Übergabe der Dateipfade von den ausgewählten Bildern zu erstellen, sollte ja auch nicht das Problem sein.

^Hättest du sowas schon als Quelltext vorliegen? (glaube kaum, dass ich gleich so gut mit wxPython klarkomme - hab leider derzeitig nicht so viel Zeit um das jetzt anhand von Tutorials oder Büchern zu lernen...)
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi Tux

Ich hab mal schnell ein Beispiel zusammengepflastert, hat keine Kommentare drin, falls du Fragen hast einfach stellen.

Auswählen kannst du wie im Explorer:

Code: Alles auswählen

import wx
import os
import sys

class ImageFrame(wx.Frame):
    def __init__(self, title, folder, width, height):
        wx.Frame.__init__(self, None, -1, title, size=(640,480))
        self.folder = folder
        self.width = width
        self.height = height

        self._gui()
        self.image_list = wx.ImageList(width, height, True)
        self.folderview.AssignImageList(self.image_list, wx.IMAGE_LIST_NORMAL)

        self.images = self.load_images(folder)
        for bitmap, name, path in self.images:
            bitmap_id = self.image_list.Add(bitmap)

            self.folderview.InsertImageStringItem(sys.maxint, name, bitmap_id)

    def load_images(self, folder):
        images = []
        for image_name in os.listdir(folder):
            if image_name.endswith('.jpg'):
                image_path = os.path.join(folder, image_name)
                image = wx.Image(image_path, wx.BITMAP_TYPE_ANY)

                # ignoriert Seitenverhaeltnis, sonst nur Breite angeben und Hoehe
                # mit (BildBreite/float(BildHoehe))*Breite ausrechnen
                image = image.Scale(self.width, self.height, wx.IMAGE_QUALITY_HIGH)
                images.append( (wx.BitmapFromImage(image), image_name, image_path) )
        return images

    def _gui(self):
        self.main_panel = wx.Panel(self)

        self.folderview = wx.ListCtrl(self.main_panel, style=wx.LC_ICON|wx.LC_AUTOARRANGE)

        self.ok_button = wx.Button(self.main_panel, label='Tu was mit den Bildern')
        self.ok_button.Bind(wx.EVT_BUTTON, self.on_accept)

        self.cancel_button = wx.Button(self.main_panel, label='Nein doch nicht')
        self.cancel_button.Bind(wx.EVT_BUTTON, self.on_decline)

        self._layout()

    def on_accept(self, event):
        if self.folderview.GetFirstSelected() != -1:
            selected = [self.folderview.GetFirstSelected()]
            select_count = self.folderview.GetSelectedItemCount()

            for index in xrange(select_count-1):
                item_id = self.folderview.GetNextSelected(selected[-1])
                selected.append(item_id)

            print 'Selected Items:'
            for item_id in selected:
                print '%2d: %s' % (item_id, self.images[item_id][2])

    def on_decline(self, event):
        pass

    def _layout(self):
        main_sizer = wx.BoxSizer(wx.VERTICAL)
        main_sizer.Add(self.folderview, 1, flag=wx.EXPAND)

        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        button_sizer.Add(self.ok_button, 0, flag=wx.ALL, border=10)
        button_sizer.Add(self.cancel_button, 0, flag=wx.ALL, border=10)

        main_sizer.Add(button_sizer, 0, flag=wx.ALIGN_CENTER)

        self.main_panel.SetSizerAndFit(main_sizer)

if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = ImageFrame('Images', '.', 96, 96)
    frame.Show()
    app.SetTopWindow(frame)
    app.MainLoop()
Gruss
Antworten