self.bmp.SetBitmap(pic) RuntimeError: wrapped C/C++ object of type StaticBitmap has been deleted怎么解决
时间: 2024-05-10 10:14:43 浏览: 8
这个错误通常发生在使用 wxPython 等 GUI 框架时,由于对象被删除或销毁,但仍然在尝试访问该对象时引起的。解决方法是在使用该对象之前检查该对象是否存在,如果不存在,则不要访问该对象。
例如,在使用 wxPython 的 StaticBitmap 控件时,可以使用以下代码来检查该控件是否存在:
```
if not self.bmp:
return
```
这将在控件不存在时跳过该代码段,避免引发 RuntimeError。
相关问题
# coding=utf-8 # 文件位置: code\cho13\ch13_8_4.py import wx class MyFrame(wx.Frame): def __init__(self): super().__init__(None, title='静态图片控制', size=(300, 300)) self.panel = wx.Panel(parent=self) self.bmps = [wx.Bitmap('images/3.jpg', wx.BITMAP_TYPE_JPG), wx.Bitmap('images/4.jpg', wx.BITMAP_TYPE_JPG), wx.Bitmap('images/1.webp', wx.BITMAP_TYPE_WEBP)] b1 = wx.Button(self.panel, id=1, label='Button1') b2 = wx.Button(self.panel, id=1, label='Button2') self.Bind(wx.EVT_BUTTON, self.on_click, id=1, id2=2) self.image = wx.StaticBitmap(self.panel, bitmap=self.bmps[0]) vbox = wx.BoxSizer(wx.VERTICAL) vbox.Add(b1, proportion=1, flag=wx.EXPAND) vbox.Add(b2, proportion=1, flag=wx.EXPAND) vbox.Add(self.image, proportion=3, flag=wx.EXPAND) self.panel.SetSizer(vbox) def on_click(self, event): event_id = event.GetId() if event_id == 1: self.image.SetBitmap(self.bmps[1]) else: self.image.SetBitmap(self.bmps[2]) self.panel.Layout() app = wx.App() frm = wx.Frame frm.Show() app.MainLoop()
这段代码存在一些错误,无法正常运行。以下是错误的修正:
1. 缺少括号:`frm = wx.Frame`应该改为`frm = MyFrame()`
2. EVT_BUTTON绑定错误:应该是`self.Bind(wx.EVT_BUTTON, self.on_click, id=1)`和`self.Bind(wx.EVT_BUTTON, self.on_click, id=2)`,分别绑定id为1和2的按钮。
3. 图片路径错误:需要将图片放在与代码同级的images文件夹下。
修正后的代码如下:
```python
# coding=utf-8
# 文件位置: code\cho13\ch13_8_4.py
import wx
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title='静态图片控制', size=(300, 300))
self.panel = wx.Panel(parent=self)
self.bmps = [wx.Bitmap('images/3.jpg', wx.BITMAP_TYPE_JPG),
wx.Bitmap('images/4.jpg', wx.BITMAP_TYPE_JPG),
wx.Bitmap('images/1.webp', wx.BITMAP_TYPE_WEBP)]
b1 = wx.Button(self.panel, id=1, label='Button1')
b2 = wx.Button(self.panel, id=2, label='Button2')
self.Bind(wx.EVT_BUTTON, self.on_click, id=1)
self.Bind(wx.EVT_BUTTON, self.on_click, id=2)
self.image = wx.StaticBitmap(self.panel, bitmap=self.bmps[0])
vbox = wx.BoxSizer(wx.VERTICAL)
vbox.Add(b1, proportion=1, flag=wx.EXPAND)
vbox.Add(b2, proportion=1, flag=wx.EXPAND)
vbox.Add(self.image, proportion=3, flag=wx.EXPAND)
self.panel.SetSizer(vbox)
def on_click(self, event):
event_id = event.GetId()
if event_id == 1:
self.image.SetBitmap(self.bmps[1])
else:
self.image.SetBitmap(self.bmps[2])
self.panel.Layout()
app = wx.App()
frm = MyFrame()
frm.Show()
app.MainLoop()
```
优化这段代码HBITMAP hBmp1 = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1)); HBITMAP hBmp2 = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP2)); m_pic1.SetBitmap(hBmp1); m_pic2.SetBitmap(hBmp2);
可以考虑使用资源文件的方式来加载位图,以减少代码量和提高代码可读性。具体操作如下:
1. 在资源文件中添加位图资源,例如将 IDB_BITMAP1 和 IDB_BITMAP2 添加到资源文件中。
2. 在代码中使用以下方式加载位图:
```c++
// 加载资源
HINSTANCE hInst = AfxGetInstanceHandle();
HBITMAP hBmp1 = ::LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1));
HBITMAP hBmp2 = ::LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP2));
// 设置位图
m_pic1.SetBitmap(hBmp1);
m_pic2.SetBitmap(hBmp2);
```
这样可以避免硬编码位图路径,使代码更加清晰易懂。同时,如果需要修改位图资源,只需要在资源文件中修改即可,无需修改代码。