2011-11-11 18 views
2

私は面白い問題を抱えています。Destroy()wxpythonの単純なエラー?

このプログラムは単純な画像ビューアであり、リストボックスに異なる画像を含むことができます。リストボックスには画像の名前が含まれます。リストボックス内の項目に画像を読み込むことができます。リストボックスの任意の項目をクリックすると、その画像が表示されます。何らかの理由でDestroy()が正しく機能していません。あなたは私を理解することができない場合 1.youプレスが新しい作成、

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() 

にエラーが何であるかを確認するために、これを試してみてください、(時間の任意の量) 2.press、ロード・ファイル を次のコードを実行してください3.リストボックス上の任意の項目をクリックします(現在の項目を除く) 4.元の項目である に戻ります。5.次に、現在表示されている項目以外の項目をクリックします。

何らかの問題があります。イメージ自体は破壊されず、次のようなエラーが返されます。 (、PyDea dObjectError( 'StaticBitmapオブジェクトのC++部分が削除されましたが、属性へのアクセスが許可されなくなりました。'、)、) イメージを読み込むことはできますが、以前のイメージは削除されません。

誰もがこの状況で私を助けることができれば、この問題を言葉にするのは難しいです、それは非常に高く評価されるでしょう。それ以上の説明が必要な場合はコメントしてください。私はあなたに非常に感謝します。

+2

可能な限りコードを単純化するために、しばらく時間をとることをお勧めします。これはあなたを助けるために私たちを助けます。たとえば、コメント付きのコードを投稿するのは役に立ちません。 – joaquin

+1

問題を明らかにする小さな実行可能な例に問題を絞り込みます。理想的には、エラーを表示するために命令リストに従う必要はありません。問題に接続していない不要なコードをすべて削除してください。また、グローバル変数を取り除くことをお勧めします。代わりにオブジェクト指向のコードを使用してください。 – Fenikso

+0

あなたの説明どおりにこれを行う方法がわかりません。私も単純化するためにいくつかのものを取り除こうとしたが、物事は間違っていた。 –

答えて

3

ここでは、別の画像を読み込む際に現在の画像を消去するようにコードを修正しました。 これは基本的にself.parent.bitmap.Destroy()を使用して行われます。

変更を認識するために、コードの構造を変更せずにいくつかの変更を加えました。私はグローバル呼び出しを排除しました。どのようにグローバル変数IMAGE_LISTSELを削除し、それをクラス属性で変換したかを見てください。 RobinとFeniksoがあなたに言っていたことです。 IMAGE_NAMEIMAGE_DATAと同じことを試してください。

コードは動作していますが、依然として許容できるwxpythonコードではありません。正しく書かれたwxpythonコードの多くの例をWebで得ることができます。あなたがそれを買う余裕があれば私はあなたに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

@ user1008537まあ...あなたは実際にやった! – joaquin

0

bmp1とbitmap1をローカル変数として使用することも、時にはグローバル変数として使用することもあります。以前の参照を保存せずに複数のインスタンスを作成しているため、既存のオブジェクトへの参照が失われてしまいます。 Destroy()を実行すると、最も最近作成されたインスタンスのみが破棄されます。

代わりに(リストのような)何らかのコレクションにそれらを追加して、後で必要なときにリストからアイテムにアクセスできます。また、グローバル変数の使用を避けてください。変数を所属するオブジェクトインスタンスに格納します。

+0

ありがとうございますが、あなたが何を意味するのかわかりません、私に例を示してもらえますか –