Destroy()wxpython简单错误?

时间:2011-11-11 22:19:04

标签: python wxpython

我有一个有趣的问题,

此程序是一个简单的图像查看器,它可以在列表框中包含不同的图像。列表框包含图像的名称。您可以将图像加载到列表框中的项目。您可以单击列表框中的任何项目以查看其图像。由于某种原因,Destroy()无法正常运行。如果您无法理解我,请运行以下代码,

IMAGE_NAME=[]
IMAGE_DATA=[]
IMAGE_LISTSEL=[]
import sys
import wx
def deletepic(self,parent):
    try:
        bitmap1.Destroy()
        bmp1.Destroy()
    except:
        print sys.exc_info()
def sendnewpic(self,parent):
    global scroll_img
    deletepic(self,parent)  
    print IMAGE_DATA[IMAGE_LISTSEL[0]]
    if IMAGE_DATA[IMAGE_LISTSEL[0]]!='':
        try:
            print IMAGE_DATA[IMAGE_LISTSEL[0]]
            bmp1 = wx.Image(IMAGE_DATA[IMAGE_LISTSEL[0]], wx.BITMAP_TYPE_ANY).ConvertToBitmap()
            bitmap1 = wx.StaticBitmap(scroll_img, -1, bmp1, (0, 0))
        except:
            pass
def areachange(self,pg):
    print pg
    try:
        if IMAGE_DATA[IMAGE_LISTSEL[0]]=='':
            deletepic(self,parent)
    except:
        pass
    if pg=="Images":
        self.images_area.Show()
    else:
        self.images_area.Hide()
class imageMax(wx.Panel):
    pass

class imageTab(imageMax):
    def imagesel(self,parent):
        IMAGE_LISTSEL[:] = []
        IMAGE_LISTSEL.append(self.listBox.GetSelection())
        sendnewpic(self,parent)
    def newAddImage(self,parent):
        IMAGE_NAME.append('hi');
        IMAGE_DATA.append('');
        self.listBox.Set(IMAGE_NAME)
        self.listBox.SetSelection(len(IMAGE_NAME)-1)
        self.imagesel(self) #making it a selected image, globally

    def reName(self,parent):
        sel = self.listBox.GetSelection()
        text = self.listBox.GetString(sel)
        renamed = wx.GetTextFromUser('Rename item', 'Rename dialog', text)
        if renamed != '':
            IMAGE_NAME.pop(sel)
            IMAGE_NAME.insert(sel,renamed)
            self.listBox.Set(IMAGE_NAME)
            self.listBox.SetSelection(sel)
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.listBox = wx.ListBox(self, size=(200, -1), choices=IMAGE_NAME, style=wx.LB_SINGLE)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        btnSizer = wx.BoxSizer(wx.VERTICAL) #change to horizontal for side by side
        self.sizerMain = wx.BoxSizer()
        self.listBox.Bind(wx.EVT_LISTBOX_DCLICK, self.reName)
        self.listBox.Bind(wx.EVT_LISTBOX, self.imagesel)
        btn = wx.Button(self, label="Create New",size=(200, 40))
        btnTwo = wx.Button(self, label="Test 2",size=(200, 40))
        btn.Bind(wx.EVT_BUTTON, self.newAddImage)
        self.sizer.Add(self.listBox, proportion=1, flag=wx.TOP | wx.EXPAND | wx.LEFT, border=5)
        btnSizer.Add(btn, 0, wx.ALL, 5)
        btnSizer.Add(btnTwo, 0, wx.ALL, 5)
        self.sizer.Add(btnSizer)
        self.sizerMain.Add(self.sizer, proportion=0, flag=wx.BOTTOM | wx.EXPAND, border=0)
        self.SetSizer(self.sizerMain)

class MyNotebook(wx.Notebook):
    def __init__(self, *args, **kwargs):
        wx.Notebook.__init__(self, *args, **kwargs)

class MyPanel(imageTab):

    def OnClickTop(self, event):
        scroll_img.Scroll(600, 400)

    def OnClickBottom(self, event):
        scroll_img.Scroll(1, 1)

    def OnPageChanged(self, event):
        new = event.GetSelection()
        areachange(self,self.notebook.GetPageText(new))
        event.Skip()

    def OnPageChanging(self, event):
        event.Skip()
    def onOpenFile(self,parent):
        """ Open a file"""
        filename = wx.FileSelector()
        if (filename!=''):
            global bitmap1,bmp1,scroll_img
            if IMAGE_DATA[IMAGE_LISTSEL[0]]!='':
                deletepic(self,parent)
            bmp1 = wx.Image(filename, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
            bitmap1 = wx.StaticBitmap(scroll_img, -1, bmp1, (0, 0))
            scroll_img.SetScrollbars(1, 1, bmp1.GetWidth(), bmp1.GetHeight())
            IMAGE_DATA[IMAGE_LISTSEL[0]]=filename
            print IMAGE_DATA

    def __init__(self, *args, **kwargs):
        global bitmap1,bmp1,scroll_img
        wx.Panel.__init__(self, *args, **kwargs)
        self.notebook = MyNotebook(self, size=(225, -1))
#        self.button = wx.Button(self, label="Something else here? Maybe!")
        tab_images = imageTab(self.notebook)
        # add the pages to the notebook with the label to show on the tab
        self.notebook.AddPage(tab_images, "Pics",select=True)

        scroll_img = wx.ScrolledWindow(self, -1)
        scroll_img.SetScrollbars(1, 1, 600, 400)
        #self.button = wx.Button(scroll_img, -1, "Scroll Me", pos=(50, 20))
        #self.Bind(wx.EVT_BUTTON,  self.OnClickTop, self.button)
        #self.button2 = wx.Button(scroll_img, -1, "Scroll Back", pos=(500, 350))
        #self.Bind(wx.EVT_BUTTON, self.OnClickBottom, self.button2)

        self.images_area=wx.StaticBox(self, -1, '')
        self.sizerBox = wx.StaticBoxSizer(self.images_area,wx.HORIZONTAL)
        #self.load_file=wx.Button(self, label='Load File')
        #self.sizerBox.Add(self.load_file,0,wx.ALL,5)
        self.sizerBox2 = wx.BoxSizer()
        self.sizerBox.Add(scroll_img, 1, wx.EXPAND|wx.ALL, 10)
        self.sizerBox2.Add(self.sizerBox, 1, wx.EXPAND|wx.ALL, 10)
        self.sizer = wx.BoxSizer()
        self.sizer.Add(self.notebook, proportion=0, flag=wx.EXPAND)
#        self.sizer.Add(self.button, proportion=0)
        btnSizer = wx.BoxSizer() #change to horizontal for side by side
        btnTwo = wx.Button(self, label="Load File",size=(200, 40))
        btnTwo.Bind(wx.EVT_BUTTON,self.onOpenFile)

        bmp1 = None
        bitmap1 = None

        btnSizer.Add(btnTwo, 0, wx.TOP, 15)
        self.sizerBox2.Add(btnSizer)
        #self.sizerBox.Add(self.bitmap1)
        self.sizer.Add(self.sizerBox2, proportion=1, flag=wx.EXPAND)

        self.SetSizer(self.sizer)
        self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
        areachange(self,self.notebook.GetPageText(0))

class MainWindow(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        self.panel = MyPanel(self)

        self.Show()

app = wx.App(False)
win = MainWindow(None, size=(600, 400))
app.MainLoop()

试试看看错误是什么, 1.你按下新建(任意次数) 2.按,加载文件 3.单击列表框中的任何项目(您所在的项目除外) 4.然后回到你所在的原始项目, 5.然后单击除当前所在项目之外的任何项目

会出现某种问题,图像不会破坏自身并返回如下错误: (,PyDeadObjectError('已删除StaticBitmap对象的C ++部分,不再允许属性访问。'),) 我仍然能够加载图像,但以前的图像不会删除。

很难说出这个问题,如果有人能帮助我解决这个问题,我将不胜感激。如果您需要进一步说明,请评论。我非常感谢你的观看。

2 个答案:

答案 0 :(得分:3)

此处您已修复代码,以便在加载另一个图像时清除当前图像。 这基本上是使用self.parent.bitmap.Destroy()完成的。

我在不改变代码结构的情况下修改了一些内容,以便您识别更改。我删除了全局调用。看看我如何消除全局IMAGE_LISTSEL变量并将其转换为类属性。这就是罗宾和菲尼索告诉你的。尝试对IMAGE_NAMEIMAGE_DATA执行相同操作。

虽然代码工作正常,但仍远未接受wxpython代码。您可以在Web中获得许多正确编写的wxpython代码示例。如果你负担得起,我建议你wxPython in Action from Noel Rappin and Robin Dunn

IMAGE_NAME = []
IMAGE_DATA = []

import sys
import wx

def deletepic(self):
    try:
        self.parent.bitmap.Destroy()
    except:
        print sys.exc_info()

def sendnewpic(self):
    if self.parent.bitmap: deletepic(self)  
    if IMAGE_DATA[self.image_listsel] != '':
        try:
            print IMAGE_DATA[self.image_listsel]
            bmp = wx.Image(IMAGE_DATA[self.image_listsel], wx.BITMAP_TYPE_ANY).ConvertToBitmap()
            self.parent.scroll_img.SetScrollbars(1, 1, bmp.GetWidth(), bmp.GetHeight())
            self.parent.bitmap = wx.StaticBitmap(self.parent.scroll_img, -1, bmp, (0, 0))
            self.parent.Refresh()
        except:
            pass

def areachange(self, pg):
    print pg
    try:
        if IMAGE_DATA[self.image_listsel] == '':
            deletepic(self)
    except:
        pass

    if pg == "Images":
        self.images_area.Show()
    else:
        self.images_area.Hide()


class imageTab(wx.Panel):

    def __init__(self, parent, grandparent):
        wx.Panel.__init__(self, parent)
        self.parent = grandparent
        self.image_listsel = 0
        self.listBox = wx.ListBox(self, size=(200, -1), choices=IMAGE_NAME, style=wx.LB_SINGLE)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        btnSizer = wx.BoxSizer(wx.VERTICAL) #change to horizontal for side by side
        self.sizerMain = wx.BoxSizer()
        self.listBox.Bind(wx.EVT_LISTBOX_DCLICK, self.reName)
        self.listBox.Bind(wx.EVT_LISTBOX, self.imagesel)
        btn = wx.Button(self, label="Create New",size=(200, 40))
        btnTwo = wx.Button(self, label="Test 2",size=(200, 40))
        btn.Bind(wx.EVT_BUTTON, self.newAddImage)
        self.sizer.Add(self.listBox, proportion=1, flag=wx.TOP | wx.EXPAND | wx.LEFT, border=5)
        btnSizer.Add(btn, 0, wx.ALL, 5)
        btnSizer.Add(btnTwo, 0, wx.ALL, 5)
        self.sizer.Add(btnSizer)
        self.sizerMain.Add(self.sizer, proportion=0, flag=wx.BOTTOM | wx.EXPAND, border=0)
        self.SetSizer(self.sizerMain)

    def imagesel(self, evt):
        self.image_listsel = self.listBox.GetSelection()
        sendnewpic(self)

    def newAddImage(self, evt):
        IMAGE_NAME.append('hi')
        IMAGE_DATA.append('')
        self.listBox.Set(IMAGE_NAME)
        self.listBox.SetSelection(len(IMAGE_NAME)-1)
        self.imagesel(None) #making it a selected image, globally

    def reName(self,parent):
        sel = self.listBox.GetSelection()
        text = self.listBox.GetString(sel)
        renamed = wx.GetTextFromUser('Rename item', 'Rename dialog', text)
        if renamed != '':
            IMAGE_NAME.pop(sel)
            IMAGE_NAME.insert(sel,renamed)
            self.listBox.Set(IMAGE_NAME)
            self.listBox.SetSelection(sel)


class MyPanel(wx.Panel):

    def __init__(self, *args, **kwargs):

        wx.Panel.__init__(self, *args, **kwargs)
        self.notebook = wx.Notebook(self, size=(225, -1))
# 
        self.tab_images = imageTab(self.notebook, self)
        # add the pages to the notebook with the label to show on the tab
        self.notebook.AddPage(self.tab_images, "Pics", select=True)

        self.scroll_img = wx.ScrolledWindow(self, -1)
        self.scroll_img.SetScrollbars(1, 1, 600, 400)

        self.images_area = wx.StaticBox(self, -1, '')
        self.sizerBox = wx.StaticBoxSizer(self.images_area, wx.HORIZONTAL)

        self.sizerBox2 = wx.BoxSizer()
        self.sizerBox.Add(self.scroll_img, 1, wx.EXPAND|wx.ALL, 10)
        self.sizerBox2.Add(self.sizerBox, 1, wx.EXPAND|wx.ALL, 10)
        self.sizer = wx.BoxSizer()
        self.sizer.Add(self.notebook, proportion=0, flag=wx.EXPAND)
#
        btnSizer = wx.BoxSizer() #change to horizontal for side by side
        btnTwo = wx.Button(self, label="Load File", size=(200, 40))
        btnTwo.Bind(wx.EVT_BUTTON, self.onOpenFile)

        self.bmp = None
        self.bitmap = None

        btnSizer.Add(btnTwo, 0, wx.TOP, 15)
        self.sizerBox2.Add(btnSizer)
        #
        self.sizer.Add(self.sizerBox2, proportion=1, flag=wx.EXPAND)

        self.SetSizer(self.sizer)
        self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
        areachange(self, self.notebook.GetPageText(0))

    def OnClickTop(self, event):
        self.scroll_img.Scroll(600, 400)

    def OnClickBottom(self, event):
        self.scroll_img.Scroll(1, 1)

    def OnPageChanged(self, event):
        new = event.GetSelection()
        areachange(self, self.notebook.GetPageText(new))
        event.Skip()

    def OnPageChanging(self, event):
        event.Skip()

    def onOpenFile(self, evt):
        """ Open a file"""
        filename = wx.FileSelector()
        if filename != '':
            IMAGE_DATA[ self.tab_images.image_listsel] = filename
            self.tab_images.imagesel(None)
            print IMAGE_DATA


class MainWindow(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        self.panel = MyPanel(self)
        self.Show()


app = wx.App(False)
win = MainWindow(None, size=(600, 400))
app.MainLoop()

答案 1 :(得分:0)

有时您使用bmp1和bitmap1作为局部变量,有时使用全局变量。由于您在不保存先前引用的情况下创建它们的多个实例,因此您将丢失对已存在对象的引用。当你Destroy()它们时,你只是在破坏最近创建的实例。

尝试将它们添加到某种类型的集合(如列表)中,然后您可以在以后需要时访问列表中的任何项目。还要尽量避免使用全局变量。将变量存储在它们所属的对象实例中。