【问题标题】:Scaling background image with frame size using wx python使用 wx python 缩放具有帧大小的背景图像
【发布时间】:2018-11-08 18:05:41
【问题描述】:

我一直在尝试最终拥有一个使用简单矢量图像作为背景的应用程序,因此可以根据需要缩放和调整屏幕大小。我暂时用光栅照片对此进行了测试,并试图通过以下链接拼凑一些东西:

https://www.blog.pythonlibrary.org/2010/03/18/wxpython-putting-a-background-image-on-a-panel/ How to resize and draw an image using wxpython? wxPython Background image on frame

不幸的是,我是个菜鸟,虽然我了解了正在发生的事情的要点,但我没有足够的经验来为自己的目的修改它。话虽如此,如何在面板上保留背景图像并使用 wxpython 实时缩放面板大小的图像?

我现在有一些拼凑的代码:

import pathlib
import wx

class MainApp(wx.App):

    def __init__(self, redirect=False, filename=None):

        wx.App.__init__(self, redirect, filename)
        dlg = MainFrame(parent=None,title="IvyVine")
        dlg.Show()

####################################

class MainFrame(wx.Frame):

    def __init__(self, parent, title):

        wx.Frame.__init__(self, parent=None, title="IvyVine",size=(1000,500))
        panel = MainPanel(self)
        self.Center()

        self.Show(True)

    def OnExit(self,e):
        self.Close(True) #Closes the frame

####################################

class MainPanel(wx.Panel):

    def __init__(self, parent):

        bg_img = 'window.JPG'

        wx.Panel.__init__(self, parent=parent)
        self.SetBackgroundStyle(wx.BG_STYLE_ERASE)
        self.frame = parent
        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(3):
            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_SIZE, self.OnSize)
        self.Bind(wx.EVT_PAINT, self.OnPaint)

    #---------------------------

    def scale_bg(self, bitmap, width, height):

        pass

    #---------------------------

    def OnSize(self, size):

        self.Layout()
        self.Refresh()

    #---------------------------

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

        # The image I'm using is very large, and this math only captures a part of it for some reason.
        xPos = (cliWidth - self._width)/2
        yPos = (cliHeight - self._height)/2
        #img = self.scale_bg(self.bg)
        dc.DrawBitmap(self.bg, xPos, yPos)

#################################

if __name__ == "__main__":

    app = MainApp()
    app.MainLoop()

****编辑的代码****

####################################

类 MainPanel(wx.Panel):

def __init__(self, parent):

    bg_img = 'window.JPG'

    wx.Panel.__init__(self, parent=parent)
    self.SetBackgroundStyle(wx.BG_STYLE_ERASE)
    self.frame = parent
    self.bg = wx.Image(bg_img, wx.BITMAP_TYPE_ANY)
    #store sizes
    self.bgh = self.bg.GetHeight()
    self.bgw = self.bg.GetWidth()

    sizer = wx.BoxSizer(wx.VERTICAL)
    hSizer = wx.BoxSizer(wx.HORIZONTAL)

    for num in range(3):
        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_SIZE, self.OnSize)
    self.Bind(wx.EVT_PAINT, self.OnPaint)

#---------------------------

def OnSize(self, size):

    self.Layout()
    self.Refresh()

#---------------------------

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

    #calculate scale factors
    fw = cliWidth / float(self.bgw)
    fh = cliHeight / float(self.bgh)
    scaledimage = self.bg_img.Scale(fw, fh)

    dc.DrawBitmap(wx.Bitmap(scaledimage))
#

【问题讨论】:

    标签: python background panel wxwidgets frame


    【解决方案1】:

    首先,不要使用wx.Image,它不能缩放。使用wx.Image

    def __init__(self, parent):
    
        bg_img = 'window.JPG'
    
        wx.Panel.__init__(self, parent=parent)
        self.SetBackgroundStyle(wx.BG_STYLE_ERASE)
        self.frame = parent
        self.bg = wx.Image(bg_img, wx.BITMAP_TYPE_ANY)
        #---store sizes---
        self.bgh = bg.GetHeight()
        self.bgw = bg.GetWidth()
    

    接下来,在您的 Draw 函数中,缩放图像并进行绘制

    def Draw(self, dc):
    
        cliWidth, cliHeight = self.GetClientSize()
        if not cliWidth or not cliHeight:
            return
        dc.Clear()
    
        # Calculate scale factors
        # The final image will be distorted. Change this maths for "fit in window", but leaving margins
        fw = cliWidth / float(self.bgw)
        fh = cliHeight / float(self.bgh)
        scaledimage = self.bg.Scale(fw, fh)
    
        #dc wants a Bitmap
        dc.DrawBitmap(wx.Bitmap(scaledimage))
    

    【讨论】:

    • 谢谢!只有一个问题;如何启动绘图方法?目前程序背景仍为空白
    • @WatcherMagic。奇怪的。您的Draw 是从OnPaint 调用的,这应该从MainFrame.Show 自动发生。使用调试器来确保它被调用。旁注:自从fh,fw 计算错误以来,我已经编辑了我的答案,但这与看不到图像无关。
    • 我有一个错误说'MainPanel object as no attribute bg_img',我已经编辑了我的帖子以获得当前代码。 (感谢指正!)
    • @WatcherMagic 哦,对不起,我的错。它必须是 bg(一个 wx.Image)而不是 bg_img(一个文本)。我已经编辑了我的答案。
    • 哦,有道理!谢谢!没有太大变化,关于 "C++ 断言 "(width > 0) && (height > 0)" failed at ..\..\src\common\image.cpp(433) in wxImage::Scale(): invalid新的图像尺寸”。我打算用数学做实验,如果有什么可行的,我会发布。
    【解决方案2】:

    Image.Scale 方法等待整数。应该给出图像的新尺寸而不是比例。

    另外,DC.DrawBitmap 方法缺少图像在面板中的位置作为输入参数 (x=0, y=0)。

    通过这些修复,Draw 方法变为:

         def Draw(self, dc):
        
            cliWidth, cliHeight = self.GetClientSize()
            if not cliWidth or not cliHeight:
                return
            dc.Clear()
        
            #Scale to client size
            scaledimage = self.bg_img.Scale(cliWidth, cliHeight)
            dc.DrawBitmap(wx.Bitmap(scaledimage), 0, 0)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-21
      • 1970-01-01
      • 2016-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-20
      • 2012-07-26
      相关资源
      最近更新 更多