Notebook-Größe des Inhalts anpassen!

Plattformunabhängige GUIs mit wxWidgets.
Antworten
andreaszdw
User
Beiträge: 24
Registriert: Donnerstag 12. Oktober 2006, 07:28

Hallo,

ich habe folgenden Code:

Code: Alles auswählen

import wx
import os
import flc

class PageOne(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        flc.FileListCtrl(self, -1)

#----------------------------------------------------------#
class DasFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(600, 400))
                
        # Menü
        menubar = wx.MenuBar()
        file = wx.Menu()
        file.Append(101, '&Beenden', 'Programm beenden')

        menubar.Append(file, '&Datei')
        
        edit = wx.Menu()
        edit.Append(201, '&Einstellungen', 'Einstellungen bearbeiten')
        menubar.Append(edit, '&Bearbeiten')
        
        self.SetMenuBar(menubar)
        
        #flc.FileListCtrl(self, -1)
        # Here we create a panel and a notebook on the panel
        panel = wx.Panel(self)
        notebook = wx.Notebook(panel)

        # create the page windows as children of the notebook
        page1 = PageOne(notebook)
        page2 = PageOne(notebook)

        # add the pages to the notebook with the label to show on the tab
        notebook.AddPage(page1, "Archivieren")
        notebook.AddPage(page2, "Arch2")

        # finally, put the notebook in a sizer for the panel to manage
        # the layout
        sizer = wx.BoxSizer()
        sizer.Add(notebook, 1, wx.EXPAND)
        panel.SetSizer(sizer)
        
        self.statusbar = self.CreateStatusBar()
        self.statusbar.SetStatusText(os.getcwd())

        # Events Menü
        self.Bind(wx.EVT_MENU, self.OnQuit, id=101)
        self.Bind(wx.EVT_MENU, self.OnPreferences, id=201)
        self.Bind(flc.EVT_DOUBLE_CLICK, self.checkdoubleclickflc)
        
    # Programm beenden
    def OnQuit(self, event):
        self.Close()
        
    # Einstellungen bearbeiten    
    def OnPreferences(self, event):
        teststring = os.path.expanduser('~') + '/.dsammler'
        self.statusbar.SetStatusText(teststring)

    def checkdoubleclickflc(self, event):
        self.statusbar.SetStatusText(os.getcwd())
        pass
        
#----------------------------------------------------------#
class DasApp(wx.App):
    def OnInit(self):
        frame = DasFrame(None, -1, "Das")
        frame.Show(True)
        self.SetTopWindow(frame)
        # Todo
        # prüfen ob Datei für Einstellungen existiert,
        # sonst anlegen und somit den Speicherort festlegen
        # eventuell noch prüfen, ob mehrere Mandanten vorliegen
        if not os.path.isfile(os.path.expanduser('~') + '/.dsammler'):
            outfile=open(os.path.expanduser('~') + '/.dsammler',"w")
            outfile.write("Out File")
            outfile.close()

        return True

#----------------------------------------------------------#
def main():
    """
    Hauptprozedur
    """
   
    app = DasApp(0)
    # Hier geht es erst weiter, wenn alle Fenster geschlossen wurden.
    app.MainLoop()


#----------------------------------------------------------#
if __name__ == "__main__":
    main()
Das auf den panel liegende ListCtrl passt sich leider nicht dem Notebook an und füllt nur einen kleinen Ausschnitt links oben. Wie passe ich die Größe an?
BlackJack

Wo kommt denn `flc.FileListCtrl` her? Schon probiert es in einen Sizer zu stecken mit dem Flag, dass es in den verfügbaren Platz expandieren soll?

Sonst fällt mir noch auf, dass man keine IDs selbst erfinden sollte. Das betrifft die Menüs. Und statt einer -1 sollte man dann `wx.ID_ANY` verwenden. wxPython ist mittlerweile doch recht objektorientiert und braucht die explizite Indirektion über IDs fast gar nicht mehr. Die `Menu.Append()`-Methode gibt ein MenuItem-Objekt zurück, das man später beim `Bind()` direkt verwenden kann. Einfach als drittes Argument angeben; ohne Schlüsselwort.

Pfade sollten mit `os.path.join()` zusammengesetzt werden und Konstanten sollten nicht mehrfach literal im Quelltext wiederholt werden. Die bindet man besser *einmal* an einen Namen und verwendet dann diesen.
andreaszdw
User
Beiträge: 24
Registriert: Donnerstag 12. Oktober 2006, 07:28

Code: Alles auswählen

import wx
import os
import flc

datei_einstellungen = os.path.join (os.path.expanduser('~'), ".dsammler")

class PageOne(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        flc.FileListCtrl(self, wx.ID_ANY)        

#----------------------------------------------------------#
class DasFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(600, 400))
                
        # Menü
        menubar = wx.MenuBar()
        file = wx.Menu()
        file_id = file.Append(wx.ID_ANY, '&Beenden', 'Programm beenden')

        menubar.Append(file, '&Datei')
        
        edit = wx.Menu()
        edit_id = edit.Append(wx.ID_ANY, '&Einstellungen', 'Einstellungen bearbeiten')
        menubar.Append(edit, '&Bearbeiten')
        
        self.SetMenuBar(menubar)
        
        #flc.FileListCtrl(self, -1)
        # Here we create a panel and a notebook on the panel
        panel = wx.Panel(self)
        notebook = wx.Notebook(panel)

        # create the page windows as children of the notebook
        page1 = PageOne(notebook)
        page2 = PageOne(notebook)

        # add the pages to the notebook with the label to show on the tab
        notebook.AddPage(page1, "Archivieren")
        notebook.AddPage(page2, "Arch2")

        # finally, put the notebook in a sizer for the panel to manage
        # the layout
        sizer = wx.BoxSizer()
        sizer.Add(notebook, 1, wx.EXPAND)
        panel.SetSizer(sizer)
        
        self.statusbar = self.CreateStatusBar()
        self.statusbar.SetStatusText(os.getcwd())

        # Events Menü
        self.Bind(wx.EVT_MENU, self.OnQuit, file_id)
        self.Bind(wx.EVT_MENU, self.OnPreferences, edit_id)
        self.Bind(flc.EVT_DOUBLE_CLICK, self.checkdoubleclickflc)
        
    # Programm beenden
    def OnQuit(self, event):
        self.Close()
        
    # Einstellungen bearbeiten    
    def OnPreferences(self, event):
        ausgabe = os.path.expanduser('~')
        self.statusbar.SetStatusText(ausgabe)

    def checkdoubleclickflc(self, event):
        self.statusbar.SetStatusText(os.getcwd())
        pass
        
#----------------------------------------------------------#
class DasApp(wx.App):
    def OnInit(self):
        frame = DasFrame(None, -1, "Das")
        frame.Show(True)
        self.SetTopWindow(frame)
        # Todo
        # prüfen ob Datei für Einstellungen existiert,
        # sonst anlegen und somit den Speicherort festlegen
        # eventuell noch prüfen, ob mehrere Mandanten vorliegen
        if not os.path.isfile(datei_einstellungen):
            outfile=open(datei_einstellungen, "w")
            outfile.write("Out File")
            outfile.close()

        return True
#----------------------------------------------------------#
def main():
    """
    Hauptprozedur
    """
   
    app = DasApp(0)
    # Hier geht es erst weiter, wenn alle Fenster geschlossen wurden.
    app.MainLoop()


#----------------------------------------------------------#
if __name__ == "__main__":
    main()
Die Änderungen habe ich vorgenommen. Hier Jetzt FileListCtrl:

Code: Alles auswählen

import wx
import os
import time


#----------------------------------------------------------#
#--- eigene Nachricht um an parent Fenster zu schicken ----#
class FlcDoubleClick(wx.PyCommandEvent):
    def __init__(self, evtType, id):
        wx.PyCommandEvent.__init__(self, evtType, id)
        
myEVT_DOUBLE_CLICK = wx.NewEventType()
EVT_DOUBLE_CLICK = wx.PyEventBinder(myEVT_DOUBLE_CLICK)

#----------------------------------------------------------#
class MyPopupMenu(wx.Menu):
    def __init__(self):
        wx.Menu.__init__(self)
        
        self.test = 0
        
        item = wx.MenuItem(self, wx.NewId(), "Archivieren")
        self.AppendItem(item)
        self.Bind(wx.EVT_MENU, self.archivieren, item)
        item = wx.MenuItem(self, wx.NewId(),"Loeschen")
        self.AppendItem(item)
        self.Bind(wx.EVT_MENU, self.loeschen, item)

    def archivieren(self, item):
        self.test = 1
        print item

    def loeschen(self):
        self.test = 2

#----------------------------------------------------------#
class FileListCtrl(wx.ListCtrl):
    def __init__(self, parent, id):
        wx.ListCtrl.__init__(self, parent, id, style=wx.LC_REPORT)

        self.parent = parent
        
        images = ['images/unknown.png', 
                  'images/up16.png',
                  'images/folder.png',
                  'images/png.png',
                  'images/tif.png',
                  'images/gif.png',
                  'images/bmp.png',
                  'images/pdf.png',
                  'images/py.png',
                  'images/pyc.png',
                  'images/jpg.png']
        
        self.il = wx.ImageList(16, 16)
        for i in images:
            self.il.Add(wx.Bitmap(i))
        self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)

        self.readDir()

        self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)
        self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)

    def readDir(self):
        self.ClearAll()

        # Überschriften
        self.InsertColumn(0, 'Name')
        self.InsertColumn(1, 'Ext')
        self.InsertColumn(2, 'Size', wx.LIST_FORMAT_RIGHT)
        self.InsertColumn(3, 'Modified')

        # breiten Vorgeben
        self.SetColumnWidth(0, 220)
        self.SetColumnWidth(1, 70)
        self.SetColumnWidth(2, 100)
        self.SetColumnWidth(3, 420)
        j = 1

        # der erste Eintrag '..' mit Bild
        self.InsertStringItem(0, '..') 
        self.SetItemImage(0, 1)

        
        #files = os.listdir('.')

        # Dateien-Liste
        filelist = [f for f in os.listdir('.') if os.path.isfile(os.path.join('.', f))]

        # Verzeichnis-Liste
        dirlist = [f for f in os.listdir('.') if os.path.isdir(os.path.join('.', f))]

        # Ausgabe Verzeichnisse
        for i in dirlist:
            (name, ext) = os.path.splitext(i)
            ex = ext[1:]
            sec = os.path.getmtime(i)
            self.InsertStringItem(j, name)
            self.SetStringItem(j, 3, time.strftime('%Y-%m-%d %H:%M', time.localtime(sec)))
            
            self.SetItemImage(j, 2) 

            if (j % 2) == 0:
                self.SetItemBackgroundColour(j, '#e6f1f5')
            j = j + 1

        # Ausgabe Dateien
        for i in filelist:
            (name, ext) = os.path.splitext(i)
            ex = ext[1:]
            size = os.path.getsize(i)
            sec = os.path.getmtime(i)
            self.InsertStringItem(j, name)
            self.SetStringItem(j, 1, ex)
            self.SetStringItem(j, 2, str(size) + ' B')
            self.SetStringItem(j, 3, time.strftime('%Y-%m-%d %H:%M', time.localtime(sec)))

            self.SetListImage (i, j, ex)

            if (j % 2) == 0:
                self.SetItemBackgroundColour(j, '#e6f1f5')
            j = j + 1
            
    # Bilder nach Dateiendungen
    def SetListImage(self, i, j, ex):
        if ex == 'png':
            self.SetItemImage(j, 3)
        elif ex == 'tif':
            self.SetItemImage(j, 4)
        elif ex == 'gif':
            self.SetItemImage(j, 5)
        elif ex == 'bmp':
            self.SetItemImage(j, 6)
        elif ex == 'pdf':
            self.SetItemImage(j, 7)
        elif ex == 'py':
            self.SetItemImage(j, 8)
        elif ex == 'pyc':
            self.SetItemImage(j, 9)
        elif ex == 'jpg':
            self.SetItemImage(j, 10)
        else:
            self.SetItemImage(j, 0) 

    # Rechtsklick
    def OnRightDown(self, event):
        self.PopupMenu(MyPopupMenu())
        tmpItem, tmpWhere = self.HitTest(event.GetPosition()) # Item herausfinden
        
    # Doppelklick    
    def OnDoubleClick(self, event):
        #--- Nachricht an Elternfenster wenn Verzeichnis geändert wurde
        if self.GetItemText(self.GetFocusedItem()) == '..':
            os.chdir(os.pardir) 
        else:
            pathdir = os.path.join(os.getcwd(), self.GetItemText(self.GetFocusedItem()))
            #pathdir = '%s\%s' % (os.getcwd() , self.GetItemText(self.GetFocusedItem()))
            if os.path.isdir(pathdir) == True:
                os.chdir(pathdir)

        # Verzeichnis neu einlesen
        self.readDir()
        evt = FlcDoubleClick(myEVT_DOUBLE_CLICK, self.GetId())
        self.GetEventHandler().ProcessEvent(evt)
Was muss ich ändern damit es im Notebook die komplette Größe ausfüllt?
BlackJack

@andreaszdw: Naja, was ich schon gesagt habe: Du musst das `FileListCtrl` in einen Sizer stecken und dabei sagen, dass es den Platz ausfüllen soll. Das hast Du mit dem `Notebook` im `Frame` doch auch schon gemacht. Sonst hätte das `Notebook` den `Frame` auch nicht ausgefüllt.
andreaszdw
User
Beiträge: 24
Registriert: Donnerstag 12. Oktober 2006, 07:28

Alles klar, habs geschnallt, jetzt läufts:

Code: Alles auswählen

class PageOne(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        sizer = wx.BoxSizer()
        self.f = flc.FileListCtrl(self, wx.ID_ANY)
        sizer.Add(self.f, 1, wx.EXPAND)
        self.SetSizer(sizer)
Vielen Dank!
Antworten