Python - Bitmap不会在按钮上绘制/显示

时间:2010-06-11 06:45:34

标签: python wxpython custom-controls

我一直在研究这个项目已经有一段时间了 - 它本来应该是一个测试,看看是否使用wxPython,我可以从头开始构建一个按钮。从头开始意味着:我可以完全控制按钮的所有方面(即控制显示的BMP ......事件处理程序做了什么......等等)

我遇到了几个问题(因为这是我的第一个主要的 python项目。)现在,当所有代码都在我的生活中工作时,我无法显示图像。

基本代码 - 无效

    dc = wx.BufferedPaintDC(self)
    dc.SetFont(self.GetFont())
    dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
    dc.Clear()
    dc.DrawBitmap(wx.Bitmap("/home/wallter/Desktop/Mouseover.bmp"), 100, 100)

    self.Refresh()
    self.Update()

Full Main.py

import wx
from Custom_Button import Custom_Button
from wxPython.wx import *

ID_ABOUT = 101
ID_EXIT  = 102

class MyFrame(wx.Frame):
    def __init__(self, parent, ID, title):
        wxFrame.__init__(self, parent, ID, title,
                         wxDefaultPosition, wxSize(400, 400))

        self.CreateStatusBar()
        self.SetStatusText("Program testing custom button overlays")
        menu = wxMenu()
        menu.Append(ID_ABOUT, "&About", "More information about this program")
        menu.AppendSeparator()
        menu.Append(ID_EXIT, "E&xit", "Terminate the program")
        menuBar = wxMenuBar()
        menuBar.Append(menu, "&File");
        self.SetMenuBar(menuBar)

        # The call for the 'Experiential button' 
        self.Button1 = Custom_Button(parent, -1, 
                                     wx.Point(100, 100),
                                     wx.Bitmap("/home/wallter/Desktop/Mouseover.bmp"),
                                     wx.Bitmap("/home/wallter/Desktop/Normal.bmp"),
                                     wx.Bitmap("/home/wallter/Desktop/Click.bmp"))

        # The following three lines of code are in place to try to get the 
        # Button1 to display (trying to trigger the Paint event (the _onPaint.)
        # Because that is where the 'draw' functions are. 
        self.Button1.Show(true)  
        self.Refresh()
        self.Update()

        # Because the Above three lines of code did not work, I added the 
        # following four lines to trigger the 'draw' functions to test if the 
        # '_onPaint' method actually worked.
        # These lines do not work.
        dc = wx.BufferedPaintDC(self)
        dc.SetFont(self.GetFont())
        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
        dc.DrawBitmap(wx.Bitmap("/home/wallter/Desktop/Mouseover.bmp"), 100, 100)

        EVT_MENU(self, ID_ABOUT, self.OnAbout)
        EVT_MENU(self, ID_EXIT,  self.TimeToQuit)

    def OnAbout(self, event):
        dlg = wxMessageDialog(self, "Testing the functions of custom "
                              "buttons using pyDev and wxPython",
                              "About", wxOK | wxICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()


    def TimeToQuit(self, event):
        self.Close(true)



class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(NULL, -1, "wxPython | Buttons")
        frame.Show(true)
        self.SetTopWindow(frame)
        return true

app = MyApp(0)
app.MainLoop()

完整CustomButton.py

import wx
from wxPython.wx import *

class Custom_Button(wx.PyControl):

    def __init__(self, parent, id, Pos, Over_BMP, Norm_BMP, Push_BMP,  **kwargs):
        wx.PyControl.__init__(self,parent, id, **kwargs)

        self.Bind(wx.EVT_LEFT_DOWN, self._onMouseDown)
        self.Bind(wx.EVT_LEFT_UP, self._onMouseUp)
        self.Bind(wx.EVT_LEAVE_WINDOW, self._onMouseLeave)
        self.Bind(wx.EVT_ENTER_WINDOW, self._onMouseEnter)
        self.Bind(wx.EVT_ERASE_BACKGROUND,self._onEraseBackground)
        self.Bind(wx.EVT_PAINT,self._onPaint)

        self.pos = Pos

        self.Over_bmp = Over_BMP
        self.Norm_bmp = Norm_BMP
        self.Push_bmp = Push_BMP

        self._mouseIn = False
        self._mouseDown = False

    def _onMouseEnter(self, event):
        self._mouseIn = True

    def _onMouseLeave(self, event):
        self._mouseIn = False

    def _onMouseDown(self, event):
        self._mouseDown = True

    def _onMouseUp(self, event):
        self._mouseDown = False
        self.sendButtonEvent()

    def sendButtonEvent(self):
        event = wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, self.GetId())
        event.SetInt(0)
        event.SetEventObject(self)
        self.GetEventHandler().ProcessEvent(event)

    def _onEraseBackground(self,event):
        # reduce flicker
        pass

    def Iz(self):
        dc = wx.BufferedPaintDC(self)
        dc.DrawBitmap(self.Norm_bmp, 100, 100)

    def _onPaint(self, event):
        # The printing functions, they should work... but don't.
        dc = wx.BufferedPaintDC(self)
        dc.SetFont(self.GetFont())
        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
        dc.Clear()
        dc.DrawBitmap(self.Norm_bmp)

        # This never printed... I don't know if that means if the EVT
        # is triggering or what.
        print '_onPaint'

        # draw whatever you want to draw
        # draw glossy bitmaps e.g. dc.DrawBitmap
        if self._mouseIn:   # If the Mouse is over the button
            dc.DrawBitmap(self.Over_bmp, self.pos)
        else: # Since the mouse isn't over it Print the normal one
              # This is adding on the above code to draw the bmp
              # in an attempt to get the bmp to display; to no avail.
            dc.DrawBitmap(self.Norm_bmp, self.pos)
        if self._mouseDown: # If the Mouse clicks the button
            dc.DrawBitmap(self.Push_bmp, self.pos)

此代码不起作用?我没有显示BMP为什么?我怎么得到一个?我已经让staticBitmap(...)显示一个,但它不会移动,调整大小或其他任何事情...... - 它只在框架的左上角?

注意:框架是400pxl X 400pxl - 和“/home/wallter/Desktop/Mouseover.bmp”

1 个答案:

答案 0 :(得分:1)

你确定你的代码是否正常运行,因为当我运行它时会出现很多错误,请阅读以下几点,你应该有一个至少正确绘制的按钮

  1. 当运行它时,它会给出错误,因为Custom_Button传递NULL parent而不是传递帧,例如Custom_Button(self, ...)

  2. 您的drawBitmap调用也是错误的,它会引发异常,而不是dc.DrawBitmap(self.Norm_bmp)它应该是dc.DrawBitmap(self.Norm_bmp, 0, 0)

  3. dc.DrawBitmap(self.Over_bmp, self.pos)也会抛出错误,因为pos应该是x,而不是元组,所以改为dc.DrawBitmap(self.Over_bmp, *self.pos)

  4. 最后你不需要“从wxPython.wx import *”而不是“从wx import *”而不是wxXXX类名使用wx.XXX,而不是true使用True

  5. 这是我的工作代码

    from wx import *
    
    ID_ABOUT = 101
    ID_EXIT  = 102
    
    
    class Custom_Button(wx.PyControl):
    
        def __init__(self, parent, id, Pos, Over_BMP, Norm_BMP, Push_BMP,  **kwargs):
            wx.PyControl.__init__(self,parent, id, **kwargs)
    
            self.Bind(wx.EVT_LEFT_DOWN, self._onMouseDown)
            self.Bind(wx.EVT_LEFT_UP, self._onMouseUp)
            self.Bind(wx.EVT_LEAVE_WINDOW, self._onMouseLeave)
            self.Bind(wx.EVT_ENTER_WINDOW, self._onMouseEnter)
            self.Bind(wx.EVT_ERASE_BACKGROUND,self._onEraseBackground)
            self.Bind(wx.EVT_PAINT,self._onPaint)
    
            self.pos = Pos
    
            self.Over_bmp = Over_BMP
            self.Norm_bmp = Norm_BMP
            self.Push_bmp = Push_BMP
    
            self._mouseIn = False
            self._mouseDown = False
    
        def _onMouseEnter(self, event):
            self._mouseIn = True
    
        def _onMouseLeave(self, event):
            self._mouseIn = False
    
        def _onMouseDown(self, event):
            self._mouseDown = True
    
        def _onMouseUp(self, event):
            self._mouseDown = False
            self.sendButtonEvent()
    
        def sendButtonEvent(self):
            event = wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, self.GetId())
            event.SetInt(0)
            event.SetEventObject(self)
            self.GetEventHandler().ProcessEvent(event)
    
        def _onEraseBackground(self,event):
            # reduce flicker
            pass
    
        def Iz(self):
            dc = wx.BufferedPaintDC(self)
            dc.DrawBitmap(self.Norm_bmp, 100, 100)
    
        def _onPaint(self, event):
            # The printing functions, they should work... but don't.
            dc = wx.BufferedPaintDC(self)
            dc.SetFont(self.GetFont())
            dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
            dc.Clear()
            dc.DrawBitmap(self.Norm_bmp, 0, 0)
    
            # This never printed... I don't know if that means if the EVT
            # is triggering or what.
            print '_onPaint'
    
            # draw whatever you want to draw
            # draw glossy bitmaps e.g. dc.DrawBitmap
            if self._mouseIn:   # If the Mouse is over the button
                dc.DrawBitmap(self.Over_bmp, *self.pos)
            else: # Since the mouse isn't over it Print the normal one
                  # This is adding on the above code to draw the bmp
                  # in an attempt to get the bmp to display; to no avail.
                dc.DrawBitmap(self.Norm_bmp, *self.pos)
            if self._mouseDown: # If the Mouse clicks the button
                dc.DrawBitmap(self.Push_bmp, *self.pos)
    
    class MyFrame(wx.Frame):
        def __init__(self, parent, ID, title):
            wx.Frame.__init__(self, parent, ID, title,
                             wx.DefaultPosition, wx.Size(400, 400))
    
            self.CreateStatusBar()
            self.SetStatusText("Program testing custom button overlays")
            menu = wx.Menu()
            menu.Append(ID_ABOUT, "&About", "More information about this program")
            menu.AppendSeparator()
            menu.Append(ID_EXIT, "E&xit", "Terminate the program")
            menuBar = wx.MenuBar()
            menuBar.Append(menu, "&File");
            self.SetMenuBar(menuBar)
    
            # The call for the 'Experiential button' 
            s = r"D:\virtual_pc\mockup\mockupscreens\embed_images\toolbar\options.png"
            self.Button1 = Custom_Button(self, -1, 
                                         wx.Point(100, 100),
                                         wx.Bitmap(s),
                                         wx.Bitmap(s),
                                         wx.Bitmap(s))
    
            self.Button1.Show(True)  
    
            EVT_MENU(self, ID_ABOUT, self.OnAbout)
            EVT_MENU(self, ID_EXIT,  self.TimeToQuit)
    
        def OnAbout(self, event):
            dlg = wxMessageDialog(self, "Testing the functions of custom "
                                  "buttons using pyDev and wxPython",
                                  "About", wxOK | wxICON_INFORMATION)
            dlg.ShowModal()
            dlg.Destroy()
    
    
        def TimeToQuit(self, event):
            self.Close(true)
    
    
    
    class MyApp(wx.App):
        def OnInit(self):
            frame = MyFrame(None, -1, "wxPython | Buttons")
            frame.Show(True)
            self.SetTopWindow(frame)
            return True
    
    app = MyApp(0)
    app.MainLoop()