wxPython之wx.DC

wx.DC

  能够在电脑显示器上显示对象,是GUI工具包最基本的功能之一。对于wxPython,对象通过发送给设备上下文(Device Context, DC)的绘制命令显示在屏幕上。在底层,所有控件都是以位图形式绘制在屏幕上。DC的接口允许自定义控件的外观。
  所有可见地显示在屏幕上的窗口发出一些绘制命令给DC,告诉系统哪些像素信息显示在屏幕上。一些控件类,例如wx.Control, wx.Window和wx.Panel,允许通过使用wx.EVT_PAINT,自定义控件在屏幕上显示什么。

示例说明

创建一个滑动显示窗口部件,用来显示目录下PNG或JPG文件。

#-*-coding: UTF-8 -*-
#------------------------------------------------------
#Purpose: nothing....

#Author: 阿Bin先生
#Created: 2017年5月21日
#------------------------------------------------------
import os
import wx

class SlideShowPanel(wx.PyPanel):
    def __init__(self, parent):
        super(SlideShowPanel, self).__init__(parent)
        # Attributes
        self.idx = 0 # Current index in image list
        self.images = list() # list of images found to display
        # Event Handlers
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_LEFT_UP, self.Next)
        self.Bind(wx.EVT_RIGHT_UP, self.Previous)
        self.SetImageDir("E:/TestData")

    def DoGetBestSize(self):
        """Virtual override for PyPanel"""
        newsize = wx.Size(0, 0)
        if len(self.images):
            imgpath = self.images[self.idx]
            bmp = wx.Bitmap(imgpath)
            newsize = bmp.GetSize()
            newsize = newsize + (20, 20) # some padding
        else:
            tsize = self.GetTextExtent("No Image!")
            newsize = tsize + (20, 20)
            # Ensure new size is at least 300x300
            return wx.Size(max(300, newsize[0]),
            max(300, newsize[1]))

    def OnPaint(self, event):
        """Draw the image on to the panel"""
        dc = wx.PaintDC(self) # Must create a PaintDC
        # Get the working rectangle
        rect = self.GetClientRect()
        # Setup the DC
        dc.SetTextForeground(wx.BLACK)
        # Do the drawing
        if len(self.images):
            # Draw the current image
            imgpath = self.images[self.idx]
            bmp = wx.Bitmap(imgpath)
            bsize = bmp.GetSize()
            # Try and center the image
            # Note: assumes image is smaller than canvas
            xpos = (rect.width - bsize[0]) / 2
            ypos = (rect.height - bsize[1]) / 2
            dc.DrawBitmap(bmp, xpos, ypos)
            # Draw a label under the image saying what
            # number in the set it is.
            imgcount = len(self.images)
            number = "%d / %d" % (self.idx+1, imgcount)
            tsize = dc.GetTextExtent(number)
            xpos = (rect.width - tsize[0]) / 2
            ypos = ypos + bsize[1] + 5 # 5px below image
            dc.DrawText(number, xpos, ypos)
        else:
            # Display that there are no images
            font = self.GetFont()
            font.SetWeight(wx.FONTWEIGHT_BOLD)
            dc.SetFont(font)
            dc.DrawLabel("No Images!", rect, wx.ALIGN_CENTER)

    def Next(self, event):
        """Goto next image"""
        self.idx += 1
        if self.idx >= len(self.images):
            self.idx = 0 # Go back to zero
        self.Refresh() # Causes a repaint

    def Previous(self, event):
        """Goto previous image"""
        self.idx -= 1
        if self.idx < 0:
            self.idx = len(self.images) - 1 # Goto end
        self.Refresh() # Causes a repaint

    def SetImageDir(self, imgpath):
        """Set the path to where the images are"""
        assert os.path.exists(imgpath)
        # Find all the images in the directory
        self.images = [ os.path.join(imgpath, img)
                for img in os.listdir(imgpath)
                if img.lower().endswith('.png') or
                img.lower().endswith('.jpg') ]
        self.idx = 0

class MyFrame(wx.Frame):
    def __init__(self, parent, *args, **kwargs):
        super(MyFrame, self).__init__(parent, *args, **kwargs)
        # Attributes
        self.mypanel = SlideShowPanel(self)
        self.mypanel.SetBackgroundColour(wx.WHITE)

class MyApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(None, title="wx.DC",size = [1000, 900])
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True

if __name__ == "__main__":
    app = MyApp(False)
    app.MainLoop()

运行结果:

这里写图片描述

示例分析

  SlideShowPanel继承于PyPanel,以至于能够访问它的一些虚方法。DoGetBestSize方法是虚重写。绑定绘制处理器给EVT_PAINT事件。鼠标左击向前预览,鼠标右击向后预览。Refresh方法导致系统发出EVT_PAINT事件。
   OnPaint方法,首先实例一个PaintDC对象,PaintDC提供了DC的接口,允许绘制外观在屏幕上。GetClientRect获取控件的客户端区域。DC的DrawBitmap方法绘制图片对象到屏幕上,DC的DrawLabel方法绘制文本。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值