wxPython框架上的背景图片 [英] wxPython Background image on frame

查看:139
本文介绍了wxPython框架上的背景图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

MMGP回答,但不会让我相信他是对的;-)因此,我至少在这里提及他. (我终于把他归功于他了……8-)

MMGP Answerd but wont let me credit him right ;-) So I will at least mention him here. (And I did finally get to credit him... 8-)

他关于Double Buffering的链接讨论提供了可进行以下修改的基本代码:

His linked discussion on Double Buffering provided a base code that worked with the following modifications:

在第106行开始插入此代码(覆盖现有代码,直到到达此处显示的最后一行):

Insert this beginning at line 106 (overwritting existing code until you get to the last line shown here):

    # 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):

我整天都在反对我.

我刚开始使用wxPython模块绘制图形,当我需要在框架上绘制背景图像时,我发现

I'm new to drawing graphics with the wxPython modules, and when I needed to draw a background image on a frame I found this code which works well if the image is the full size of the window.

但是,我需要放置公司徽标作为背景,并通过调整大小使其居中.在当前形式下,调整大小会导致带有小国家大小的图形伪像出现在任何调整大小事件中.

However, I need to place a company logo as the background, and have it remain centered through resizes. In it's current form the resize causes a graphic artifact the size of a small nation to appear on the screen with any resize event.

徽标图像文件(在代码的第43行上使用)是400x300(WxH)的图像.

The logo image file (used on line 43 of the code) is a 400x300 (WxH) image.

我正在寻找一种方法来实现以下目的:快速调整图像大小以匹配wx.GetClientSize(), 或避免/消除伪影的方法.最好不涉及PIL或ImageMagick. App必须仅在本地级别运行,并且与系统无关(Win,Lin和Mac),这都不涉及网络活动或映射的驱动器.

I am looking for a way to either: resize my image on the fly to match wx.GetClientSize(), or a way to avoid/remove the artifact. Preferably without involving PIL or ImageMagick. App has to function on a local level only, and be system agnostic (Win, Lin and Mac), none of this involves network activities or mapped drives.

Python 2.7和wxPython 2.8

Python 2.7 and wxPython 2.8

我正在使用的代码(带我的修改注释)如下:

The code I am using (with my modification annotated) is as follows:

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

更新:最新失败-将第37行修改为52

Update: Latest Failure - Modified lines 37 to 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)

另一种尝试,另一种失败.屏幕输出无差异.此外,有关双缓冲的参考文档不能解决此问题,但是会带来相同的结果.这段代码修改了原始代码的第36至57行.

Another attempt and another fail. No difference in the output to screen. Additionally, the referenced document on double buffering does not address this issue, but does suffer from the same result. This code modifies lines 36 through 57 of the original.

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)

推荐答案

从注释中我建议使用双缓冲图形,但在编辑后的文章中没有看到.另外,当使用self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)时,我遇到了一些绘图问题.但是这条线可能对我以外的其他系统很有帮助,所以我想保留它.因此,为了处理这种情况,以下是更新的代码,该代码使用双缓冲绘图并且在这里可以正常工作:

From the comments I suggested using double buffered drawing, but I didn't see that in the edited post. Also, I had several drawing issues when self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) was used. But this line might be helpful in other systems beyond mine, so I wanted to keep it. So, in order to handle the situation, here is a updated code that uses double buffered drawing and works fine here:

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

方法OnEraseBackground故意为空.

这篇关于wxPython框架上的背景图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆