python ObjectListView 用空行更新显示,即使列表具有有效数据

发布于 2024-10-18 20:42:09 字数 16245 浏览 0 评论 0原文

我有一个更新 ObjectListView 的列表,它以前可以工作,但是在解决另一个问题时,我以某种方式破坏了它,但现在无法弄清楚为什么它不工作。

当程序解析目录时,它应该使用找到的 .mp3 文件的信息更新列表视图。它正在更新显示,但仅包含空行。但是,如果强制输出到命令行,则表明列表的内容是正确的。

更让我困惑的是,我还有第二个列表,它充当一种“日志”。它工作正常,并且它们都使用相同的技术来更新各自的列表。我已经检查了代码以找到我的拼写错误在哪里(我猜测),但我一生都无法弄清楚为什么这现在不起作用。

未正确更新的列表是 TrackOlv。要查看操作中的错误,只需浏览到包含 .mp3 文件的源目录,然后选择目标目录。您将看到显示更新为空行而不是数据行。

#Boa:Frame:Frame1

import wx
import os
import glob
import shutil
import datetime
from mutagen.mp3 import MP3
from mutagen.easyid3 import EasyID3
import mutagen.id3
import unicodedata

from ObjectListView import ObjectListView, ColumnDefn



########################################################################     
class Track(object):
    def __init__(self, title, artist, album, source, dest):
        """
        Model of the Track Object
        Contains the followign attributes:
        'Title', 'Artist', 'Album', 'Source', 'Dest'
        """

        self.atrTitle = title
        self.atrArtist = artist
        self.atrAlbum = album
        self.atrSource = source
        self.atrDest = dest        


class Action(object):
    def __init__(self, timestamp, action, result):
        self.timestamp = timestamp
        self.action = action
        self.result = result

########################################################################
# Non GUI
########################################################################

def selectFolder(sMessage):
    print "Select Folder"
    dlg = wx.DirDialog(None, message = sMessage)

    if dlg.ShowModal() == wx.ID_OK:
        # User has selected something, get the path, set the window's title to the path
        filename = dlg.GetPath()   
    else:
        filename = "None Selected"

    dlg.Destroy()
    return filename 

def getList(SourceDir):
    print "getList"
    listOfFiles = None
    print "-list set to none"

    listOfFiles = glob.glob(SourceDir + '/*.mp3')

    return listOfFiles

def getListRecursive(SourceDir):
    print "getListRecursive"
    listOfFiles = None
    listOfFiles = []
    print "-list set to none"

    for root, dirs, files in os.walk(SourceDir):
        for file in files:
            if file.endswith(".mp3"):
                listOfFiles.append(os.path.join(root,file))

    #print listOfFiles

    return listOfFiles

def strip_accents(s):
    print "strip_accents"
    return ''.join((c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn'))   

def replace_all(text):
    print "replace_all " + text
    dictionary = {'\\':"", '?':"", '/':"", '...':"", ':':"", '&':"and"}

    print "-- repl_orig: " + text
    print "-- repl_decode: " + text.decode('utf-8')

    text = strip_accents(text.decode('utf-8'))

    for i, j in dictionary.iteritems():
        text = text.replace(i,j)

    return text

def getTitle(fileName):
    print "getTitle"
    audio = MP3(fileName)

    try:
        sTitle = str(audio["TIT2"])
    except KeyError:
        sTitle = os.path.basename(fileName)
        frame.lvActions.Append([datetime.datetime.now(),fileName,"Title tag does not exist, set to filename"])

    # TODO: Offer to set title to filename
    ## If fileName != filename then
    ##  prompt user for action
    ##  Offer Y/n/a

    sTitle = replace_all(sTitle)

    return sTitle

def getArtist(fileName):
    print "get artist"

    audio = MP3(fileName)

    try:
        sArtist = str(audio["TPE1"])
    except KeyError:
        sArtist = "unkown"
        frame.lvActions.Append([datetime.datetime.now(),fileName,"Artist tag does not exist, set to unkown"])

    #Replace all special chars that cause dir path errors
    sArtist = replace_all(sArtist)

    #if name = 'The Beatles' change to 'Beatles, The'
    if sArtist.lower().find('the') == 0:
        sArtist = sArtist.replace('the ',"")
        sArtist = sArtist.replace('The ',"")
        sArtist = sArtist + ", The"

    return sArtist

def getAblum(fileName):
    print "get album"
    audio = MP3(fileName)

    try:
        sAlbum = str(audio["TALB"])
    except KeyError:
        sAlbum = "unkown"
        frame.lvActions.Append([datetime.datetime.now(),fileName,"Album tag does not exist, set to unkown"])

    #Replace all special chars that cause dir path error    
    sAlbum = replace_all(sAlbum)
    return sAlbum


########################################################################
# GUI
########################################################################
class MainPanel(wx.Panel):
    #----------------------------------------------------------------------
    def __init__(self, parent):
        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)

        #Create Track Object List
        self.TrackOlv = ObjectListView(self, wx.ID_ANY, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
        self.TrackOlv.cellEditMode = ObjectListView.CELLEDIT_SINGLECLICK
        self.setTracks()  

        #Create Actions Objet List
        self.ActionsOlv = ObjectListView(self, wx.ID_ANY, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
        self.setActions()         

        # create browse to source button
        sourceBtn = wx.Button(self, wx.ID_ANY, "Browse Source")
        sourceBtn.Bind(wx.EVT_BUTTON, self.onBrowseSource)        

        # create source txt box
        self.txSource = wx.TextCtrl(self, wx.ID_ANY, name=u'txSource', value=u'')

        # create browse dest button
        destBtn = wx.Button(self, wx.ID_ANY, "Browse Destination")
        destBtn.Bind(wx.EVT_BUTTON, self.onBrowseDest)

        # create dest txt box 
        self.txDest = wx.TextCtrl(self, wx.ID_ANY, name=u'txDest', value=u'')         

        # create Move Files button
        moveBtn = wx.Button(self, wx.ID_ANY, "Move Files")
        moveBtn.Bind(wx.EVT_BUTTON, self.onMoveFiles)

        # print list button - debug only
        printBtn = wx.Button(self, wx.ID_ANY, "Print List")
        printBtn.Bind(wx.EVT_BUTTON, self.onPrintBtn)

        # create check box to include all sub files
        self.cbSubfolders = wx.CheckBox(self, wx.ID_ANY,
              label=u'Include Subfolders', name=u'cbSubfolders', style=0)
        self.cbSubfolders.SetValue(True)
        self.cbSubfolders.Bind(wx.EVT_CHECKBOX, self.OnCbSubfoldersCheckbox)

        # create check box to repace file names
        self.cbReplaceFilename = wx.CheckBox(self, wx.ID_ANY,
              label=u'Replace Filename with Title Tag',
              name=u'cbReplaceFilename', style=0)
        self.cbReplaceFilename.SetValue(False)
        self.cbReplaceFilename.Bind(wx.EVT_CHECKBOX, self.OnCbReplaceFilenameCheckbox)

        # Create some sizers
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        feedbackSizer = wx.BoxSizer(wx.VERTICAL)
        sourceSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer = wx.BoxSizer(wx.HORIZONTAL) 

        feedbackSizer.Add(self.TrackOlv, 1, wx.ALL|wx.EXPAND, 2)
        feedbackSizer.Add(self.ActionsOlv, 1, wx.ALL|wx.EXPAND, 2)

        sourceSizer.Add(sourceBtn, 0, wx.ALL, 2)
        sourceSizer.Add(self.txSource, 1, wx.ALL|wx.EXPAND, 2)

        sourceSizer.Add(destBtn, 0, wx.ALL, 2)
        sourceSizer.Add(self.txDest, 1, wx.ALL|wx.EXPAND, 2)

        btnSizer.Add(printBtn)
        btnSizer.Add(moveBtn, 0, wx.ALL, 2)
        btnSizer.Add(self.cbSubfolders, 0, wx.ALL, 2)
        btnSizer.Add(self.cbReplaceFilename, 0, wx.ALL, 2)

        mainSizer.Add(feedbackSizer, 1 , wx.ALL|wx.EXPAND, 2)
        mainSizer.Add(sourceSizer, 0, wx.ALL|wx.EXPAND, 2)
        #mainSizer.Add(destSizer, 0, wx.ALL|wx.EXPAND, 2)
        #mainSizer.Add(destSizer, 0, wx.All|wx.Expand, 2)
        mainSizer.Add(btnSizer, 0, wx.ALL, 2)
        self.SetSizer(mainSizer)
        mainSizer.Fit(self)

    #----------------------------------------------------------------------
    # Set the GUI column headers and width
    #----------------------------------------------------------------------
    def setTracks(self, data=None):
        self.TrackOlv.SetColumns([
            ColumnDefn("Title", "left", 100, "title"),
            ColumnDefn("Artist", "left", 100, "artist"),
            ColumnDefn("Album", "left", 100, "album"),
            ColumnDefn("Source", "left", 300, "source"),
            ColumnDefn("Destination", "left", 300, "dest"),
        ]) 

    def setActions(self, data=None):
        self.ActionsOlv.SetColumns([
            ColumnDefn("Time", "left", 100, "timestamp"),
            ColumnDefn("Action", "left", 450, "action"),
            ColumnDefn("Result", "left", 450, "result")
        ])

    #----------------------------------------------------------------------
    # GUI EVENTS
    #-----------------------------------------------------------------------

    #Select Source of files
    def onBrowseSource(self, event):
        print "OnBrowseSource"    
        source = selectFolder("Select the Source Directory")

        print "--source :" + source

        self.txSource.SetValue(source)
        self.anEvent = Action(datetime.datetime.now(),source,"Set as Source dir")
        self.ActionsOlv.AddObject(self.anEvent)

        self.populateList()

    #Select Source of files
    def onBrowseDest(self, event):
        print "OnBrowseDest"    
        dest = selectFolder("Select the Destination Directory")

        print dest

        self.txDest.SetValue(dest)
        self.anEvent = Action(datetime.datetime.now(),dest,"Set as Destination dir")
        self.ActionsOlv.AddObject(self.anEvent)

        self.populateList()

    def OnCbSubfoldersCheckbox(self, event):
        print "cbSubfolder"
        self.populateList()       

    def OnCbReplaceFilenameCheckbox(self, event):
        print "cbReplaceFilename"
        self.populateList()

    def onMoveFiles(self, event):
        print "onMoveFiles"
        self.moveFiles()

    def onPrintBtn(self, event):
        print "onPrintBtn"

        #Why does this work
        #rowObj = self.dataOlv.GetSelectedObject()
        #print rowObj.author
        #print rowObj.title

        #debug - how many item in the list... why does it only print 1?
        itemcount = self.TrackOlv.GetItemCount()        
        print "-- itemcount: " + str(itemcount)

        getData = self.TrackOlv.GetItemData(1)
        print "-- getData: " + str(getData)       

        trackList = self.TrackOlv.GetObjects()        
        for tracks in trackList:         
            print tracks.atrTitle, tracks.atrArtist, tracks.atrAlbum, tracks.atrSource, tracks.atrDest


    #-------------
    #Computations
    #-------------

    def defineDestFilename(self, sFullDestPath):
        print "define dest"

        iCopyX = 0
        bExists = False
        sOrigName = sFullDestPath

        #If the file does not exist return original path/filename
        if os.path.isfile(sFullDestPath) == False:
            print "-" + sFullDestPath + " is valid"
            return sFullDestPath

        #Add .copyX.mp3 to the end of the file and retest until a new filename is found
        while bExists == False:
            sFullDestPath = sOrigName
            iCopyX += 1
            sFullDestPath = sFullDestPath + ".copy" + str(iCopyX) + ".mp3"
            if os.path.isfile(sFullDestPath) == False:
                print "-" + sFullDestPath + " is valid"
                self.lvActions.Append([datetime.datetime.now(),"Desitnation filename changed since file exists",sFullDestPath])
                bExists = True

        #return path/filename.copyX.mp3
        return sFullDestPath


    def populateList(self):
        print "populateList"

        sSource = self.txSource.Value
        sDest = self.txDest.Value

        #Initalize list to reset all values on any option change
        itemcount = self.TrackOlv.GetItemCount()        
        print "-- itemcount: " + str(itemcount)
        if itemcount > 0:
            self.TrackOlv.DeleteAllItems()
            print "--list cleaned"

        #Create list of files
        if self.cbSubfolders.Value == True:
            listOfFiles = getListRecursive(sSource)
        else:
            listOfFiles = getList(sSource)    

        print listOfFiles

        #prompt if no files detected
        if listOfFiles == []:
            self.anEvent = Action(datetime.datetime.now(),"Parse Source for .MP3 files","No .MP3 files in source directory")
            self.ActionsOlv.AddObject(self.anEvent)

        #Populate list after both Source and Dest are chosen
        if len(sDest) > 1 and len(sDest) > 1:     
            print "-iterate listOfFiles"

            for file in listOfFiles:

                #gest Source and Filename
                (sSource,sFilename) = os.path.split(file)
                print "-- source: " + sSource
                print "-- filename: " + sFilename

                #sFilename = os.path.basename(file)
                sTitle = getTitle(file)
                print "-- title: " + sTitle

                #Get artist
                try:
                    sArtist = getArtist(file)
                except UnicodeDecodeError:
                    print "unicode"
                    sArtist = "unkown"
                print "-- artist: " + sArtist

                #Get Album
                sAlbum = getAblum(file)
                print "-- album: " + sAlbum

                # Make dest path = sDest + Artist + Album
                sDestDir = os.path.join (sDest, sArtist)
                sDestDir = os.path.join (sDestDir, sAlbum) 

                #If file exists change destination to *.copyX.mp3
                if self.cbReplaceFilename.Value == True:
                    sDestDir = self.defineDestFilename(os.path.join(sDestDir,sTitle))
                else:
                    sDestDir = self.defineDestFilename(os.path.join(sDestDir,sFilename))
                print "-- dest: " + sDestDir

                # Populate listview with track info                
                self.aTrack = Track(sTitle,sArtist,sAlbum,sSource,sDestDir)        
                self.TrackOlv.AddObject(Track(sTitle,sArtist,sAlbum,sSource,sDestDir))
                self.Update()

                print "** ITEM ADDED **"
        else:
            print "-list not iterated"        

    def moveFiles (self):
        print "move files"

        #for track in self.TrackOlv:
        #    print "-iterate SourceDest"
        #    #create dir
        #    (sDest,filename) = os.path.split(self.TrackOlv)
        #    print "-check dest"
        #    
        #    if not os.path.exists(sDest):
        #        print "-Created dest"
        #        os.makedirs(sDest)
        #        self.lvActions.Append([datetime.datetime.now(),sDest,"Created"])
        #        self.Update()
        #        self.lvActions.EnsureVisible(self.lvActions.GetItemCount() -1)
        #
        #    #Move File
        #    print "-move file"
        #    shutil.move(SourceDest[0],SourceDest[1])
        #    self.lvActions.Append([datetime.datetime.now(),filename,"Moved"])
        #    self.Update()
        #    self.lvActions.EnsureVisible(self.lvActions.GetItemCount() -1)
        #
        #self.lvActions.Append([datetime.datetime.now(),"Move Complete","Success"])
        #self.Update()
        #self.lvActions.EnsureVisible(self.lvActions.GetItemCount() -1)    



########################################################################
class MainFrame(wx.Frame):
    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, parent=None, id=wx.ID_ANY,
                          title="MP3 Manager", size=(1024,768)) #W by H
        panel = MainPanel(self)

########################################################################
class GenApp(wx.App):

    #----------------------------------------------------------------------
    def __init__(self, redirect=False, filename=None):
        wx.App.__init__(self, redirect, filename)

    #----------------------------------------------------------------------
    def OnInit(self):
        # create frame here
        frame = MainFrame()
        frame.Show()
        return True

#----------------------------------------------------------------------
def main():
    """
    Run the demo
    """
    app = GenApp()
    app.MainLoop()

if __name__ == "__main__":
    main()

I have a list that updates ObjectListView, it previously worked, but in troubleshooting a different issue, I somehow broke it but now can't figure out why its not working.

When the program parses a directory it is supposed to updated the list view with info about .mp3 files found. It is updating the display, but only with blank lines. However, if you force an output to the command line it shows that the content of the list is correct.

To even confuse me further, I have a second list that acts as a type of 'log'. It works correctly, and they both use the same technique to update their respective lists. I have checked the code to find where (what I am guessing) my typo is, but for the life of me I can't figure out why this is now not working.

The list that is not updating correctly is TrackOlv. To see the error in action simply browse to a source dir that contains .mp3 files and then select a destination dir. You will see the display update with blank lines instead of line of data.

#Boa:Frame:Frame1

import wx
import os
import glob
import shutil
import datetime
from mutagen.mp3 import MP3
from mutagen.easyid3 import EasyID3
import mutagen.id3
import unicodedata

from ObjectListView import ObjectListView, ColumnDefn



########################################################################     
class Track(object):
    def __init__(self, title, artist, album, source, dest):
        """
        Model of the Track Object
        Contains the followign attributes:
        'Title', 'Artist', 'Album', 'Source', 'Dest'
        """

        self.atrTitle = title
        self.atrArtist = artist
        self.atrAlbum = album
        self.atrSource = source
        self.atrDest = dest        


class Action(object):
    def __init__(self, timestamp, action, result):
        self.timestamp = timestamp
        self.action = action
        self.result = result

########################################################################
# Non GUI
########################################################################

def selectFolder(sMessage):
    print "Select Folder"
    dlg = wx.DirDialog(None, message = sMessage)

    if dlg.ShowModal() == wx.ID_OK:
        # User has selected something, get the path, set the window's title to the path
        filename = dlg.GetPath()   
    else:
        filename = "None Selected"

    dlg.Destroy()
    return filename 

def getList(SourceDir):
    print "getList"
    listOfFiles = None
    print "-list set to none"

    listOfFiles = glob.glob(SourceDir + '/*.mp3')

    return listOfFiles

def getListRecursive(SourceDir):
    print "getListRecursive"
    listOfFiles = None
    listOfFiles = []
    print "-list set to none"

    for root, dirs, files in os.walk(SourceDir):
        for file in files:
            if file.endswith(".mp3"):
                listOfFiles.append(os.path.join(root,file))

    #print listOfFiles

    return listOfFiles

def strip_accents(s):
    print "strip_accents"
    return ''.join((c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn'))   

def replace_all(text):
    print "replace_all " + text
    dictionary = {'\\':"", '?':"", '/':"", '...':"", ':':"", '&':"and"}

    print "-- repl_orig: " + text
    print "-- repl_decode: " + text.decode('utf-8')

    text = strip_accents(text.decode('utf-8'))

    for i, j in dictionary.iteritems():
        text = text.replace(i,j)

    return text

def getTitle(fileName):
    print "getTitle"
    audio = MP3(fileName)

    try:
        sTitle = str(audio["TIT2"])
    except KeyError:
        sTitle = os.path.basename(fileName)
        frame.lvActions.Append([datetime.datetime.now(),fileName,"Title tag does not exist, set to filename"])

    # TODO: Offer to set title to filename
    ## If fileName != filename then
    ##  prompt user for action
    ##  Offer Y/n/a

    sTitle = replace_all(sTitle)

    return sTitle

def getArtist(fileName):
    print "get artist"

    audio = MP3(fileName)

    try:
        sArtist = str(audio["TPE1"])
    except KeyError:
        sArtist = "unkown"
        frame.lvActions.Append([datetime.datetime.now(),fileName,"Artist tag does not exist, set to unkown"])

    #Replace all special chars that cause dir path errors
    sArtist = replace_all(sArtist)

    #if name = 'The Beatles' change to 'Beatles, The'
    if sArtist.lower().find('the') == 0:
        sArtist = sArtist.replace('the ',"")
        sArtist = sArtist.replace('The ',"")
        sArtist = sArtist + ", The"

    return sArtist

def getAblum(fileName):
    print "get album"
    audio = MP3(fileName)

    try:
        sAlbum = str(audio["TALB"])
    except KeyError:
        sAlbum = "unkown"
        frame.lvActions.Append([datetime.datetime.now(),fileName,"Album tag does not exist, set to unkown"])

    #Replace all special chars that cause dir path error    
    sAlbum = replace_all(sAlbum)
    return sAlbum


########################################################################
# GUI
########################################################################
class MainPanel(wx.Panel):
    #----------------------------------------------------------------------
    def __init__(self, parent):
        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)

        #Create Track Object List
        self.TrackOlv = ObjectListView(self, wx.ID_ANY, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
        self.TrackOlv.cellEditMode = ObjectListView.CELLEDIT_SINGLECLICK
        self.setTracks()  

        #Create Actions Objet List
        self.ActionsOlv = ObjectListView(self, wx.ID_ANY, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
        self.setActions()         

        # create browse to source button
        sourceBtn = wx.Button(self, wx.ID_ANY, "Browse Source")
        sourceBtn.Bind(wx.EVT_BUTTON, self.onBrowseSource)        

        # create source txt box
        self.txSource = wx.TextCtrl(self, wx.ID_ANY, name=u'txSource', value=u'')

        # create browse dest button
        destBtn = wx.Button(self, wx.ID_ANY, "Browse Destination")
        destBtn.Bind(wx.EVT_BUTTON, self.onBrowseDest)

        # create dest txt box 
        self.txDest = wx.TextCtrl(self, wx.ID_ANY, name=u'txDest', value=u'')         

        # create Move Files button
        moveBtn = wx.Button(self, wx.ID_ANY, "Move Files")
        moveBtn.Bind(wx.EVT_BUTTON, self.onMoveFiles)

        # print list button - debug only
        printBtn = wx.Button(self, wx.ID_ANY, "Print List")
        printBtn.Bind(wx.EVT_BUTTON, self.onPrintBtn)

        # create check box to include all sub files
        self.cbSubfolders = wx.CheckBox(self, wx.ID_ANY,
              label=u'Include Subfolders', name=u'cbSubfolders', style=0)
        self.cbSubfolders.SetValue(True)
        self.cbSubfolders.Bind(wx.EVT_CHECKBOX, self.OnCbSubfoldersCheckbox)

        # create check box to repace file names
        self.cbReplaceFilename = wx.CheckBox(self, wx.ID_ANY,
              label=u'Replace Filename with Title Tag',
              name=u'cbReplaceFilename', style=0)
        self.cbReplaceFilename.SetValue(False)
        self.cbReplaceFilename.Bind(wx.EVT_CHECKBOX, self.OnCbReplaceFilenameCheckbox)

        # Create some sizers
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        feedbackSizer = wx.BoxSizer(wx.VERTICAL)
        sourceSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer = wx.BoxSizer(wx.HORIZONTAL) 

        feedbackSizer.Add(self.TrackOlv, 1, wx.ALL|wx.EXPAND, 2)
        feedbackSizer.Add(self.ActionsOlv, 1, wx.ALL|wx.EXPAND, 2)

        sourceSizer.Add(sourceBtn, 0, wx.ALL, 2)
        sourceSizer.Add(self.txSource, 1, wx.ALL|wx.EXPAND, 2)

        sourceSizer.Add(destBtn, 0, wx.ALL, 2)
        sourceSizer.Add(self.txDest, 1, wx.ALL|wx.EXPAND, 2)

        btnSizer.Add(printBtn)
        btnSizer.Add(moveBtn, 0, wx.ALL, 2)
        btnSizer.Add(self.cbSubfolders, 0, wx.ALL, 2)
        btnSizer.Add(self.cbReplaceFilename, 0, wx.ALL, 2)

        mainSizer.Add(feedbackSizer, 1 , wx.ALL|wx.EXPAND, 2)
        mainSizer.Add(sourceSizer, 0, wx.ALL|wx.EXPAND, 2)
        #mainSizer.Add(destSizer, 0, wx.ALL|wx.EXPAND, 2)
        #mainSizer.Add(destSizer, 0, wx.All|wx.Expand, 2)
        mainSizer.Add(btnSizer, 0, wx.ALL, 2)
        self.SetSizer(mainSizer)
        mainSizer.Fit(self)

    #----------------------------------------------------------------------
    # Set the GUI column headers and width
    #----------------------------------------------------------------------
    def setTracks(self, data=None):
        self.TrackOlv.SetColumns([
            ColumnDefn("Title", "left", 100, "title"),
            ColumnDefn("Artist", "left", 100, "artist"),
            ColumnDefn("Album", "left", 100, "album"),
            ColumnDefn("Source", "left", 300, "source"),
            ColumnDefn("Destination", "left", 300, "dest"),
        ]) 

    def setActions(self, data=None):
        self.ActionsOlv.SetColumns([
            ColumnDefn("Time", "left", 100, "timestamp"),
            ColumnDefn("Action", "left", 450, "action"),
            ColumnDefn("Result", "left", 450, "result")
        ])

    #----------------------------------------------------------------------
    # GUI EVENTS
    #-----------------------------------------------------------------------

    #Select Source of files
    def onBrowseSource(self, event):
        print "OnBrowseSource"    
        source = selectFolder("Select the Source Directory")

        print "--source :" + source

        self.txSource.SetValue(source)
        self.anEvent = Action(datetime.datetime.now(),source,"Set as Source dir")
        self.ActionsOlv.AddObject(self.anEvent)

        self.populateList()

    #Select Source of files
    def onBrowseDest(self, event):
        print "OnBrowseDest"    
        dest = selectFolder("Select the Destination Directory")

        print dest

        self.txDest.SetValue(dest)
        self.anEvent = Action(datetime.datetime.now(),dest,"Set as Destination dir")
        self.ActionsOlv.AddObject(self.anEvent)

        self.populateList()

    def OnCbSubfoldersCheckbox(self, event):
        print "cbSubfolder"
        self.populateList()       

    def OnCbReplaceFilenameCheckbox(self, event):
        print "cbReplaceFilename"
        self.populateList()

    def onMoveFiles(self, event):
        print "onMoveFiles"
        self.moveFiles()

    def onPrintBtn(self, event):
        print "onPrintBtn"

        #Why does this work
        #rowObj = self.dataOlv.GetSelectedObject()
        #print rowObj.author
        #print rowObj.title

        #debug - how many item in the list... why does it only print 1?
        itemcount = self.TrackOlv.GetItemCount()        
        print "-- itemcount: " + str(itemcount)

        getData = self.TrackOlv.GetItemData(1)
        print "-- getData: " + str(getData)       

        trackList = self.TrackOlv.GetObjects()        
        for tracks in trackList:         
            print tracks.atrTitle, tracks.atrArtist, tracks.atrAlbum, tracks.atrSource, tracks.atrDest


    #-------------
    #Computations
    #-------------

    def defineDestFilename(self, sFullDestPath):
        print "define dest"

        iCopyX = 0
        bExists = False
        sOrigName = sFullDestPath

        #If the file does not exist return original path/filename
        if os.path.isfile(sFullDestPath) == False:
            print "-" + sFullDestPath + " is valid"
            return sFullDestPath

        #Add .copyX.mp3 to the end of the file and retest until a new filename is found
        while bExists == False:
            sFullDestPath = sOrigName
            iCopyX += 1
            sFullDestPath = sFullDestPath + ".copy" + str(iCopyX) + ".mp3"
            if os.path.isfile(sFullDestPath) == False:
                print "-" + sFullDestPath + " is valid"
                self.lvActions.Append([datetime.datetime.now(),"Desitnation filename changed since file exists",sFullDestPath])
                bExists = True

        #return path/filename.copyX.mp3
        return sFullDestPath


    def populateList(self):
        print "populateList"

        sSource = self.txSource.Value
        sDest = self.txDest.Value

        #Initalize list to reset all values on any option change
        itemcount = self.TrackOlv.GetItemCount()        
        print "-- itemcount: " + str(itemcount)
        if itemcount > 0:
            self.TrackOlv.DeleteAllItems()
            print "--list cleaned"

        #Create list of files
        if self.cbSubfolders.Value == True:
            listOfFiles = getListRecursive(sSource)
        else:
            listOfFiles = getList(sSource)    

        print listOfFiles

        #prompt if no files detected
        if listOfFiles == []:
            self.anEvent = Action(datetime.datetime.now(),"Parse Source for .MP3 files","No .MP3 files in source directory")
            self.ActionsOlv.AddObject(self.anEvent)

        #Populate list after both Source and Dest are chosen
        if len(sDest) > 1 and len(sDest) > 1:     
            print "-iterate listOfFiles"

            for file in listOfFiles:

                #gest Source and Filename
                (sSource,sFilename) = os.path.split(file)
                print "-- source: " + sSource
                print "-- filename: " + sFilename

                #sFilename = os.path.basename(file)
                sTitle = getTitle(file)
                print "-- title: " + sTitle

                #Get artist
                try:
                    sArtist = getArtist(file)
                except UnicodeDecodeError:
                    print "unicode"
                    sArtist = "unkown"
                print "-- artist: " + sArtist

                #Get Album
                sAlbum = getAblum(file)
                print "-- album: " + sAlbum

                # Make dest path = sDest + Artist + Album
                sDestDir = os.path.join (sDest, sArtist)
                sDestDir = os.path.join (sDestDir, sAlbum) 

                #If file exists change destination to *.copyX.mp3
                if self.cbReplaceFilename.Value == True:
                    sDestDir = self.defineDestFilename(os.path.join(sDestDir,sTitle))
                else:
                    sDestDir = self.defineDestFilename(os.path.join(sDestDir,sFilename))
                print "-- dest: " + sDestDir

                # Populate listview with track info                
                self.aTrack = Track(sTitle,sArtist,sAlbum,sSource,sDestDir)        
                self.TrackOlv.AddObject(Track(sTitle,sArtist,sAlbum,sSource,sDestDir))
                self.Update()

                print "** ITEM ADDED **"
        else:
            print "-list not iterated"        

    def moveFiles (self):
        print "move files"

        #for track in self.TrackOlv:
        #    print "-iterate SourceDest"
        #    #create dir
        #    (sDest,filename) = os.path.split(self.TrackOlv)
        #    print "-check dest"
        #    
        #    if not os.path.exists(sDest):
        #        print "-Created dest"
        #        os.makedirs(sDest)
        #        self.lvActions.Append([datetime.datetime.now(),sDest,"Created"])
        #        self.Update()
        #        self.lvActions.EnsureVisible(self.lvActions.GetItemCount() -1)
        #
        #    #Move File
        #    print "-move file"
        #    shutil.move(SourceDest[0],SourceDest[1])
        #    self.lvActions.Append([datetime.datetime.now(),filename,"Moved"])
        #    self.Update()
        #    self.lvActions.EnsureVisible(self.lvActions.GetItemCount() -1)
        #
        #self.lvActions.Append([datetime.datetime.now(),"Move Complete","Success"])
        #self.Update()
        #self.lvActions.EnsureVisible(self.lvActions.GetItemCount() -1)    



########################################################################
class MainFrame(wx.Frame):
    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, parent=None, id=wx.ID_ANY,
                          title="MP3 Manager", size=(1024,768)) #W by H
        panel = MainPanel(self)

########################################################################
class GenApp(wx.App):

    #----------------------------------------------------------------------
    def __init__(self, redirect=False, filename=None):
        wx.App.__init__(self, redirect, filename)

    #----------------------------------------------------------------------
    def OnInit(self):
        # create frame here
        frame = MainFrame()
        frame.Show()
        return True

#----------------------------------------------------------------------
def main():
    """
    Run the demo
    """
    app = GenApp()
    app.MainLoop()

if __name__ == "__main__":
    main()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

对你而言 2024-10-25 20:42:09

问题是 setTracks 方法中 ColumnDefn 中的第四个参数与 Track 对象的属性名称不匹配。如果它们不完全匹配,则它将无法正确映射,并且小部件中不会显示任何内容。

因此,在 setTracks 方法中将“title”更改为“atrTitle”等,或者在 Track 对象中执行相反的操作。

这是我在使用 ObjectListView 时遇到的少数问题之一。

The problem is that the 4th argument in the ColumnDefn in your setTracks method don't match the Track object's attribute names. If they don't match exactly, then it won't map correctly and nothing will be shown in the widget.

So, change "title" to "atrTitle", etc in the setTracks method or do the reverse in the Track object.

This is one of the few got'chas I've had with ObjectListView.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文