Jas*_*ase 3 python graphics wxpython bitmap python-2.7
MMGP回答但不会让我信任他;-)所以我至少会在这里提到他.(我终于得到了他的信任...... 8-)
他关于Double Buffering的链接讨论提供了一个基本代码,它具有以下修改:
在第106行插入此开头(覆盖现有代码,直到到达此处显示的最后一行):
# Here's the actual drawing code.
cliWidth, cliHeight = self.GetClientSize()
bmp=wx.Bitmap("Logo16x9.png")
bmpWide = bmp.GetWidth()
bmpHeight = bmp.GetHeight()
img = bmp.ConvertToImage()
scaleFactor = cliWidth/bmpWide
bmp = wx.BitmapFromImage(img.Scale(int(bmpWide * scaleFactor), int(bmpHeight * scaleFactor)))
bmpWide = bmp.GetWidth()
bmpHeight = bmp.GetHeight()
xPos = (cliWidth - (bmpWide))/2
yPos = (cliHeight - (bmpHeight))/2
# altered by me
dc.DrawBitmap(bmp, xPos, yPos)
class TestFrame(wx.Frame):
Run Code Online (Sandbox Code Playgroud)
我整天都在反对这一点.
我是使用wxPython模块绘制图形的新手,当我需要在框架上绘制背景图像时,我发现这个代码在图像是窗口的完整大小时效果很好.
但是,我需要将公司徽标作为背景,并通过调整大小保持居中.在它的当前形式中,调整大小会导致一个小的国家大小的图形工件在屏幕上显示任何调整大小事件.
徽标图像文件(在代码的第43行上使用)是400x300(WxH)图像.
我正在寻找一种方法:动态调整我的图像以匹配wx.GetClientSize(),或者一种避免/删除工件的方法.优选地,不涉及PIL或ImageMagick.应用程序必须仅在本地级别运行,并且与系统无关(Win,Lin和Mac),这些都不涉及网络活动或映射驱动器.
Python 2.7和wxPython 2.8
我正在使用的代码(带有我的修改注释)如下:
import wx
########################################################################
class MainPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent=parent)
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self.frame = parent
sizer = wx.BoxSizer(wx.VERTICAL)
hSizer = wx.BoxSizer(wx.HORIZONTAL)
for num in range(4):
label = "Button %s" % num
btn = wx.Button(self, label=label)
sizer.Add(btn, 0, wx.ALL, 5)
hSizer.Add((1,1), 1, wx.EXPAND)
hSizer.Add(sizer, 0, wx.TOP, 100)
hSizer.Add((1,1), 0, wx.ALL, 75)
self.SetSizer(hSizer)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
#----------------------------------------------------------------------
def OnEraseBackground(self, evt):
"""
Add a picture to the background
"""
# yanked from ColourDB.py
dc = evt.GetDC()
# Added by me
cliWidth, cliHeight = self.GetClientSize()
if not dc:
dc = wx.ClientDC(self)
rect = self.GetUpdateRegion().GetBox()
dc.SetClippingRect(rect)
dc.Clear()
# use a 400x300 image
bmp = wx.Bitmap("Logo4x3.png")
# added by me
xPos = (cliWidth - 400)/2
yPos = (cliHeight - 300)/2
# altered by me
dc.DrawBitmap(bmp, xPos, yPos)
#dc.DrawBitmap(bmp, 0, 0)
########################################################################
class MainFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, size=(600,450))
panel = MainPanel(self)
self.Center()
########################################################################
class Main(wx.App):
""""""
#----------------------------------------------------------------------
def __init__(self, redirect=False, filename=None):
"""Constructor"""
wx.App.__init__(self, redirect, filename)
dlg = MainFrame()
dlg.Show()
#----------------------------------------------------------------------
if __name__ == "__main__":
app = Main()
app.MainLoop()
Run Code Online (Sandbox Code Playgroud)
更新:最新失败 - 修改第37至52行
if not dc:
dc = wx.ClientDC(self)
rect = self.GetUpdateRegion().GetBox()
dc.SetClippingRect(rect)
dc.Clear()
# use a 400x300 image
bmp = wx.Bitmap("Logo4x3.png")
img = bmp.ConvertToImage()
scaleFactor = cliWidth/400
bmp = wx.BitmapFromImage(img.Scale(int(400*scaleFactor),int(300*scaleFactor)))
# added by me
#xPos = (cliWidth - 400)/2
#yPos = (cliHeight - 300)/2
# altered by me
#dc.DrawBitmap(bmp, xPos, yPos)
dc.DrawBitmap(bmp, 0, 0)
Run Code Online (Sandbox Code Playgroud)
另一次尝试,另一次失败.输出与屏幕没有区别.此外,关于双缓冲的参考文档没有解决此问题,但确实遭受相同的结果.此代码修改原始的第36到57行.
brsh = wx.Brush('#000000')
if not dc:
dc = wx.ClientDC(self)
rect = self.GetUpdateRegion().GetBox()
dc.SetClippingRect(rect)
dc.SetBackground(brsh)
dc.SetDeviceOrigin(0,0)
dc.DestroyClippingRegion()
dc.Clear()
# use a 400x300 image
bmp = wx.Bitmap("Logo4x3.png")
img = bmp.ConvertToImage()
scaleFactor = cliWidth/400
bmp = wx.BitmapFromImage(img.Scale(int(400*scaleFactor),int(300*scaleFactor)))
# added by me
#xPos = (cliWidth - 400)/2
#yPos = (cliHeight - 300)/2
# altered by me
#dc.DrawBitmap(bmp, xPos, yPos)
dc.DrawBitmap(bmp, 0, 0)
Run Code Online (Sandbox Code Playgroud)
从我建议使用双缓冲绘图的评论,但我没有在编辑的帖子中看到.另外,使用时我有几个绘图问题self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM).但是这条线可能对我以外的其他系统有所帮助,所以我想保留它.所以,为了处理这种情况,这里是一个使用双缓冲绘图的更新代码,在这里工作正常:
import wx
class MainPanel(wx.Panel):
def __init__(self, parent, bg_img='Logo4x3.png'):
wx.Panel.__init__(self, parent=parent)
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self.bg = wx.Bitmap(bg_img)
self._width, self._height = self.bg.GetSize()
sizer = wx.BoxSizer(wx.VERTICAL)
hSizer = wx.BoxSizer(wx.HORIZONTAL)
for num in range(4):
btn = wx.Button(self, label="Button %s" % num)
sizer.Add(btn, 0, wx.ALL, 5)
hSizer.Add((1,1), 1, wx.EXPAND)
hSizer.Add(sizer, 0, wx.TOP, 100)
hSizer.Add((1,1), 0, wx.ALL, 75)
self.SetSizer(hSizer)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
def OnSize(self, size):
self.Layout()
self.Refresh()
def OnEraseBackground(self, evt):
pass
def OnPaint(self, evt):
dc = wx.BufferedPaintDC(self)
self.Draw(dc)
def Draw(self, dc):
cliWidth, cliHeight = self.GetClientSize()
if not cliWidth or not cliHeight:
return
dc.Clear()
xPos = (cliWidth - self._width)/2
yPos = (cliHeight - self._height)/2
dc.DrawBitmap(self.bg, xPos, yPos)
app = wx.App()
frame = wx.Frame(None, size=(400,300))
panel = MainPanel(frame)
frame.Show()
app.MainLoop()
Run Code Online (Sandbox Code Playgroud)
该方法OnEraseBackground故意为空.