3

MMGPは答えましたが、彼の功績を認めさせません;-)それで、少なくともここで彼について言及します。(そして私はついに彼を信用するようになりました... 8-)

ダブルバッファリングに関する彼のリンクされたディスカッションは、次の変更で機能するベースコードを提供しました。

これを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):

私はこれに対して一日中頭を殴っています。

wxPythonモジュールを使用してグラフィックを描画するのは初めてです。フレームに背景画像を描画する必要がある場合、画像がウィンドウのフルサイズの場合にうまく機能するこのコードを見つけました。

ただし、会社のロゴを背景として配置し、サイズ変更によって中央に配置する必要があります。現在の形式では、サイズ変更により、小さな国のサイズのグラフィックアーティファクトがサイズ変更イベントとともに画面に表示されます。

ロゴ画像ファイル(コードの43行目で使用)は400x300(WxH)画像です。

wx.GetClientSize()に一致するように画像のサイズをその場で変更する方法、またはアーティファクトを回避/削除する方法を探しています。できれば、PILやImageMagickを使用せずに。アプリはローカルレベルでのみ機能する必要があり、システムに依存しません(Win、Lin、Mac)。これには、ネットワークアクティビティやマップされたドライブは含まれません。

Python2.7およびwxPython2.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)
4

1 に答える 1

6

コメントから、ダブルバッファ描画を使用することを提案しましたが、編集された投稿ではそれがわかりませんでした。また、使用時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は意図的に空になっています。

于 2012-12-10T00:10:17.593 に答える