Destroy()wxpython简单错误?

Destroy()wxpython简单错误?,python,wxpython,Python,Wxpython,我有一个有趣的问题 这个程序是一个简单的图像查看器,它可以在一个列表框中包含不同的图像。列表框包含图像的名称。您可以将图像加载到列表框中的项目。您可以单击列表框上的任何项目以查看其图像。由于某些原因,Destroy()无法正常工作。如果您无法理解我,请运行以下代码 IMAGE_NAME=[] IMAGE_DATA=[] IMAGE_LISTSEL=[] import sys import wx def deletepic(self,parent): try: bitmap

我有一个有趣的问题

这个程序是一个简单的图像查看器,它可以在一个列表框中包含不同的图像。列表框包含图像的名称。您可以将图像加载到列表框中的项目。您可以单击列表框上的任何项目以查看其图像。由于某些原因,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)(“静态位图对象的C++部分已被删除,属性访问不再被允许”,,) 我仍然能够加载图像,但以前的图像不会删除


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

有时您将bmp1和bitmap1用作局部变量,有时用作全局变量。由于创建多个实例时未将先前的引用保存到任何位置,因此将丢失对现有对象的引用。销毁()它们时,只销毁最近创建的实例


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

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

为了让您能够识别更改,我在不更改代码结构的情况下修改了一些内容。我取消了全球电话。看看我是如何消除全局
IMAGE\u LISTSEL
变量并将其转换为class属性的。这就是罗宾和费尼克斯告诉你的。尝试对
IMAGE\u NAME
IMAGE\u DATA
执行相同的操作

尽管代码正在运行,但它仍然远远不能被wxpython代码所接受。您可以在web上获得许多正确编写的wxpython代码示例。如果你能负担得起,我向你推荐


花点时间尽可能地简化代码总是一个好主意。这有助于我们帮助你。例如,发布注释代码是没有帮助的。将您的问题缩小到可运行的小示例来演示问题-理想情况下,这样我们就不必按照任何指令列表来查看错误。删除所有与问题无关的不必要代码。我还建议去掉全局变量。改用面向对象的代码。我不知道你所描述的是如何做到这一点。我也试着删除一些东西来简化,但是事情变得错误了。谢谢,但我不知道你的意思,你能给我一个example@user1008537好。。。你真的做到了!
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()