最近我从Debian搬到了Mac OS X(Yosemite),在启动我的应用程序后在运行时终端出错:
relrin at MacBook-Relrin in ~/code/Helenae/Helenae/helenae/gui on git:dev+? workon code
=> run_wx.sh CloudStorage.py
Traceback (most recent call last):
File "/Users/savicvalera/code/Helenae/Helenae/helenae/gui/widgets/Filemanager.py", line 286, in OnSize
self.sb.SetStatusText(os.getcwd())
File "/Users/savicvalera/code/Helenae/lib/python2.7/site-packages/wx-3.0-osx_cocoa/wx/_core.py", line 16711, in __getattr__
raise PyDeadObjectError(self.attrStr % self._name)
wx._core.PyDeadObjectError: The C++ part of the StatusBar object has been deleted, attribute access no longer allowed.
然而在Debian中,这个应用程序没有说明任何错误。我该如何解决这个问题?
代码:
# -*- coding: utf-8 -*-
import os
import wx
import shutil
import ntpath
from FileListCtrl import FileListCtrl
from OptionsCtrl import OptionsCtrl
from InputDialogCtrl import InputDialog
from validators.FolderValidator import FolderValidator
from validators.FileValidator import FileValidator
from validators.ValidatorMsgDlg import ValidatorMsgDialog as MsgDlg
ID_BUTTON = 100
ID_BUTTON_WRITE = 101
ID_BUTTON_TRANSFER = 102
ID_BUTTON_CREATE_FOLDER = 103
ID_BUTTON_REMOVE_FILE = 104
ID_BUTTON_RENAME = 105
ID_NEW = 150
ID_FOLDER = 151
ID_RENAME = 152
ID_REPLACE = 153
ID_REMOVE = 154
ID_SHOW_STATUSBAR = 155
ID_OPTIONS = 156
ID_WRITE = 157
ID_COPY_FILE = 158
ID_COPY_FOLDER = 159
ID_EXIT = 200
ID_SPLITTER = 300
ID_TOOLBAR_UPDIR = 201
ID_TOOLBAR_HOME = 202
ID_TOOLBAR_REFRESH = 203
ID_TOOLBAR_HELP = 204
class FileManager(wx.Frame):
def __init__(self, parent, id, title, ico_folder):
wx.Frame.__init__(self, parent, -1, title)
self.parent = parent
self.ico_folder = ico_folder
wx.Log.SetLogLevel(0)
# file frame
self.files_folder = FileListCtrl(self, -1, ico_folder)
# options frame
self.options_frame = OptionsCtrl(self, -1, "Опции", ico_folder)
# menu
filemenu= wx.Menu()
newItem = wx.MenuItem(filemenu, ID_NEW, "&Новый файл", help='Создать новый файл в каталоге')
newItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/new.png'))
createItem = wx.MenuItem(filemenu, ID_FOLDER, "&Создать каталог", help='Создать новый каталог')
createItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/folder.png'))
copyFileItem = wx.MenuItem(filemenu, ID_COPY_FILE, "&Скопировать файл", help='Скопировать файл извне в текущий каталог')
copyFileItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/copy_file.png'))
copyFolderItem = wx.MenuItem(filemenu, ID_COPY_FOLDER, "&Скопировать каталог", help='Скопировать каталог извне в текущий каталог')
copyFolderItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/copy_folder.png'))
renameItem = wx.MenuItem(filemenu, ID_RENAME, "&Перемеиновать", help='Перемеиновать выделенный файл')
renameItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/rename.png'))
removeItem = wx.MenuItem(filemenu, ID_REPLACE, "&Перенос", help='Перенести выделенные файлы в другой каталог')
removeItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/remove.png'))
writeItem = wx.MenuItem(filemenu, ID_WRITE, "&Запись", help='Записать выделенные файлы')
writeItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/write.png'))
deleteItem = wx.MenuItem(filemenu, ID_REMOVE, "&Удалить", help='Удалить выделенные файлы')
deleteItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/delete.png'))
filemenu.AppendItem(newItem)
filemenu.AppendItem(createItem)
filemenu.AppendSeparator()
filemenu.AppendItem(copyFileItem)
filemenu.AppendItem(copyFolderItem)
filemenu.AppendSeparator()
filemenu.AppendItem(renameItem)
filemenu.AppendItem(removeItem)
filemenu.AppendItem(writeItem)
filemenu.AppendItem(deleteItem)
filemenu.AppendSeparator()
exitItem = wx.MenuItem(filemenu, ID_EXIT, "&Выход", help='Выход из приложения')
exitItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/exit.png'))
filemenu.AppendItem(exitItem)
configmenu = wx.Menu()
self.show_statusbar = configmenu.Append(ID_SHOW_STATUSBAR, 'Отображать строку статуса', 'Отображать строку статуса', kind=wx.ITEM_CHECK)
configmenu.Check(self.show_statusbar.GetId(), True)
self.preferencesItem = wx.MenuItem(filemenu, ID_OPTIONS, "&Параметры", help='Основные параметры приложения')
self.preferencesItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/preferences/preferences.png'))
configmenu.AppendItem(self.preferencesItem)
about = wx.Menu()
helpmenu = wx.Menu()
menuBar = wx.MenuBar()
menuBar.Append(filemenu, "&Файл")
menuBar.Append(configmenu, "&Настройки")
menuBar.Append(helpmenu, "&Помощь")
menuBar.Append(about, "&О программе")
self.SetMenuBar(menuBar)
# toolbar
tb = self.CreateToolBar(wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT | wx.TB_TEXT)
tb.AddSimpleTool(ID_TOOLBAR_UPDIR, wx.Bitmap(ico_folder + '/icons/ui/toolbar/up.png'), 'Up one directory')
tb.AddSimpleTool(ID_TOOLBAR_HOME, wx.Bitmap(ico_folder + '/icons/ui/toolbar/home.png'), 'Home')
tb.AddSimpleTool(ID_TOOLBAR_REFRESH, wx.Bitmap(ico_folder + '/icons/ui/toolbar/refresh.png'), 'Refresh')
tb.AddSeparator()
tb.AddSimpleTool(ID_TOOLBAR_HELP, wx.Bitmap(ico_folder + '/icons/ui/toolbar/help.png'), 'Help')
tb.Realize()
# button panel
self.sizer2 = wx.BoxSizer(wx.HORIZONTAL)
button1 = wx.Button(self, ID_BUTTON_WRITE, "F5 Запись")
button1.SetBackgroundColour('#BFD8DF')
button1.SetForegroundColour("#2F4D57")
button2 = wx.Button(self, ID_BUTTON_TRANSFER, "F6 Перенос")
button2.SetBackgroundColour('#BFD8DF')
button2.SetForegroundColour("#2F4D57")
button3 = wx.Button(self, ID_BUTTON_CREATE_FOLDER, "F7 Созд. каталог")
button3.SetBackgroundColour('#BFD8DF')
button3.SetForegroundColour("#2F4D57")
button4 = wx.Button(self, ID_BUTTON_REMOVE_FILE, "F8 Удалить")
button4.SetBackgroundColour('#BFD8DF')
button4.SetForegroundColour("#2F4D57")
button5 = wx.Button(self, ID_BUTTON_RENAME, "F9 Перемеиновать")
button5.SetBackgroundColour('#BFD8DF')
button5.SetForegroundColour("#2F4D57")
button6 = wx.Button(self, ID_EXIT, "F10 Выход")
button6.SetBackgroundColour('#BFD8DF')
button6.SetForegroundColour("#2F4D57")
self.sizer2.Add(button1, 1, wx.EXPAND)
self.sizer2.Add(button2, 1, wx.EXPAND)
self.sizer2.Add(button3, 1, wx.EXPAND)
self.sizer2.Add(button4, 1, wx.EXPAND)
self.sizer2.Add(button5, 1, wx.EXPAND)
self.sizer2.Add(button6, 1, wx.EXPAND)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.files_folder, 1,wx.EXPAND)
self.sizer.Add(self.sizer2, 0,wx.EXPAND)
self.SetSizer(self.sizer)
# events bindings
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_MENU, self.ToggleStatusBar, self.show_statusbar)
self.Bind(wx.EVT_MENU, self.ShowMenu, self.preferencesItem)
self.Bind(wx.EVT_CLOSE, self.OnExitProgramm)
# create folder
self.Bind(wx.EVT_BUTTON, self.OnCreateFolder, id=ID_BUTTON_CREATE_FOLDER)
self.Bind(wx.EVT_MENU, self.OnCreateFolder, id=ID_FOLDER)
# create file
self.Bind(wx.EVT_MENU, self.OnCreateFile, id=ID_NEW)
# toolbar events
self.Bind(wx.EVT_TOOL, self.UpDir, id=ID_TOOLBAR_UPDIR)
self.Bind(wx.EVT_TOOL, self.Home, id=ID_TOOLBAR_HOME)
self.Bind(wx.EVT_TOOL, self.RefreshFileCtrl, id=ID_TOOLBAR_REFRESH)
# copy file
self.Bind(wx.EVT_MENU, self.CopyFile, id=ID_COPY_FILE)
# copy folder
self.Bind(wx.EVT_MENU, self.CopyFolder, id=ID_COPY_FOLDER)
# define size and icon for app
size = (800, 600)
self.SetSize(size)
self.icon = wx.Icon(ico_folder + '/icons/app.ico', wx.BITMAP_TYPE_ICO)
self.SetIcon(self.icon)
self.SetMinSize(size)
self.Center()
def UpDir(self, event):
if self.files_folder.currentDir != self.files_folder.defaultDir:
self.files_folder.currentDir = self.files_folder.getParentDir(self.files_folder.currentDir)
filepath = self.files_folder.currentDir
self.files_folder.showFilesInDirectory(filepath)
def Home(self, event):
self.files_folder.currentDir = self.files_folder.defaultDir
self.files_folder.showFilesInDirectory(self.files_folder.defaultDir)
def RefreshFileCtrl(self, event):
self.files_folder.showFilesInDirectory(self.files_folder.currentDir)
def OnCreateFolder(self, event):
dlg = InputDialog(self, -1, 'Введите каталог', self.ico_folder, FolderValidator())
dlg.ShowModal()
if dlg.result is not None:
try:
new_folder = self.files_folder.currentDir + dlg.result
os.makedirs(new_folder)
except OSError:
wx.MessageBox("Вероятнее всего, такой файл или каталог уже существует!\nПожалуйста, дайте файлу другое имя.", 'Ошибка')
except Exception, exc:
wx.MessageBox("%s" % exc.message, "Ошибка")
self.files_folder.showFilesInDirectory(self.files_folder.currentDir)
dlg.Destroy()
def OnCreateFile(self, event):
dlg = InputDialog(self, -1, 'Введите имя файла и расширение', self.ico_folder, FileValidator())
dlg.ShowModal()
if dlg.result is not None:
try:
new_file = self.files_folder.currentDir + dlg.result
new_folders, filename = ntpath.split(dlg.result)
if len(new_folders) > 2:
os.makedirs(self.files_folder.currentDir + new_folders)
open(new_file, 'a').close()
except OSError:
wx.MessageBox("Вероятнее всего, такой файл или каталог уже существует!\nПожалуйста, дайте файлу другое имя.", 'Ошибка')
except Exception, exc:
wx.MessageBox("%s" % exc.message, "Ошибка")
self.files_folder.showFilesInDirectory(self.files_folder.currentDir)
dlg.Destroy()
def CopyFile(self, event):
dlg = wx.FileDialog(self, "Укажите путь к файлу", "", "", "All files (*.*)|*.*", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
if dlg.ShowModal() == wx.ID_OK:
filepath = dlg.GetPath()
dir, filename = ntpath.split(filepath)
shutil.copyfile(filepath, self.files_folder.currentDir+filename)
self.files_folder.showFilesInDirectory(self.files_folder.currentDir)
msg_dlg = MsgDlg(None, "Копирование завершено!")
msg_dlg.ShowModal()
dlg.Destroy()
def CopyMoveOperation(self, src, target, operation='copy'):
for src_dir, dirs, files in os.walk(src):
dst_dir = src_dir.replace(src, target)
if not os.path.exists(dst_dir):
os.mkdir(dst_dir)
for file_ in files:
src_file = os.path.join(src_dir, file_)
dst_file = os.path.join(dst_dir, file_)
if os.path.exists(dst_file):
os.remove(dst_file)
if operation is 'copy':
shutil.copy(src_file, dst_dir)
elif operation is 'move':
shutil.move(src_file, dst_dir)
def CopyFolder(self, event):
dlg = wx.DirDialog(self, "Укажите директорию", style=wx.DD_DEFAULT_STYLE)
if dlg.ShowModal() == wx.ID_OK:
folderpath = dlg.GetPath()
try:
new_folder = folderpath.split('/')[-1]
os.mkdir(new_folder)
# if this folder already exists - then catch exception, ignore him, and copy files right now
except OSError:
pass
self.CopyMoveOperation(folderpath, self.files_folder.currentDir+new_folder)
self.files_folder.showFilesInDirectory(self.files_folder.currentDir)
msg_dlg = MsgDlg(None, "Копирование завершено!")
msg_dlg.ShowModal()
dlg.Destroy()
def ShowMenu(self, event):
self.options_frame.Show()
def ToggleStatusBar(self, event):
if self.show_statusbar.IsChecked():
self.sb.Show()
else:
self.sb.Hide()
def OnExit(self, event):
self.Close()
def OnExitProgramm(self, event):
self.parent.Close()
def OnSize(self, event):
size = self.GetSize()
self.files_folder.ResizeColumns(size.x)
if not hasattr(self, 'sb'):
self.sb = self.CreateStatusBar()
self.sb.SetStatusText(os.getcwd())
event.Skip()
if __name__ == '__main__':
app = wx.App(0)
ico_folder = '..'
frame = FileManager(None, -1, 'CloudStorage', ico_folder)
frame.Show(True)
app.MainLoop()
答案 0 :(得分:1)
您可以使用wx.PyDeadObjectError异常捕获try异常块中的错误。
您还可以使用AttributeError异常删除hasattr。
def OnSize(self, event):
size = self.GetSize()
self.files_folder.ResizeColumns(size.x)
cwd = os.getcwd()
try:
self.sb.SetStatusText(cwd)
except AttributeError:
self.sb = self.CreateStatusBar()
self.sb.SetStatusText(cwd)
except wx.PyDeadObjectError:
pass
event.Skip()