2012-12-09 69 views
2

MMGP回答,但不會讓我相信他; - )所以我至少會在這裏提到他。 (而且我也終於可以存入他... 8-)wxPython框架上的背景圖像

His linked discussion雙緩衝前提是進行了以下修改工作基本代碼:

插入此開始在行106(overwritting現有的代碼,直到你可以看到這裏顯示的最後一行):

# 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模塊繪製圖形的新手,當我需要在一個框架上繪製背景圖像時,我發現this code如果圖像是窗口的全尺寸,效果很好。

但是,我需要將公司徽標作爲背景,並通過調整大小保持居中。在當前的形式中,調整大小會導致一個小國家的圖形人造物出現在屏幕上,並伴隨任何調整大小事件。

徽標圖像文件(用於代碼的第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() 

更新:最新失敗 - 改性線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) 

另一次嘗試和另一次失敗。屏幕輸出沒有差異。另外,關於雙緩衝的參考文檔沒有解決這個問題,但確實遭受了同樣的結果。此代碼修改原始的第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) 
+0

你指的是神器閃爍嗎?這是與雙緩衝繪圖解決,具體見http://wiki.wxpython.org/DoubleBufferedDrawing – mmgp

+0

不是一個閃爍。重繪後仍保留原始圖像的75%副本。結果看起來像兩個方塊(coloredf)重疊25%。 (推廣,標誌是方形) – Jase

+0

更好的解釋。原始圖像從不刪除。新圖像(調整大小後)正確繪製,但現在兩張圖像都在表面上。奇怪的是,新圖像在下方(較低z-索引)繪製舊圖像。 – Jase

回答

5

從我建議使用雙緩衝繪圖的評論,但我沒有看到在編輯的職位。另外,當使用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() 

方法OnEraseBackground是故意空。

+0

感謝您提供額外的代碼...我正準備嘗試從您鏈接的原始示例中刪除所有廢話。這會讓生活變得更容易。現在開始基於這個重建我的想法.... – Jase

+0

這也適用於Linux嗎?我現在無法在那裏測試它。 – mmgp

+0

我在那邊試過一些WM時失敗了,會回到這個。 – mmgp