龙空技术网

wxPython - GDI系统简介

爱好史地的coder 99

前言:

眼前兄弟们对“gdipython”大概比较注重,大家都想要剖析一些“gdipython”的相关资讯。那么小编同时在网络上网罗了一些有关“gdipython””的相关内容,希望兄弟们能喜欢,你们快快来了解一下吧!

实战wxPython系列-055

GDI(图形设备接口)是用于处理图形的接口。它用于与显示器、打印机或文件等图形设备交互。GDI允许程序员在屏幕或打印机上显示数据,而不必关心特定设备的细节。这样就将程序开发与具体的硬件实现隔离开来。

一、GDI系统

从编程的角度来看,GDI是一组处理图形的类和方法。GDI由二维矢量图形、字体和图像组成。

wxPython提供了一个称作设备上下文(Device Context, 简称DC)的对象wx.DC,所有的GDI绘图都基于该DC。同时GDI还提供基本的绘制工具,包括颜色选择wx.Colour,画笔wx.Pen,画刷wx.Brush,字体wx.Font ,调色板wx.Palette,以及关于空间定位的相关类比如矩形wx.Rect, 区域wx.Region, 点wx.Point, 尺寸wx.Size等来共同构成整个GDI系统。

图1:wxPython GDI系统示意图

二、wx.DC及其导出类

要开始绘制图形,必须创建一个设备上下文(DC)对象。在wxPython中,wx.DC定义为可以在其上绘制图形和文本的设备上下文。它旨在表示不同的输出设备,并提供了一个通用的抽象API,用于在其中任何一个设备上绘图。

wx.DC是一个抽象基类,不能直接创建。不管是在屏幕上绘图,还是打印输出,都需要选择一个派生类来完成。每个派生类都在特定的条件下使用,wxPython提供了以下wx.DC派生类:

wx.MemoryDC:内存设备上下文提供了一种将图形绘制到位图上的方法。wx.BufferedDC:提供了一种避免闪烁的简单方法:当在它上绘图时,实际上所有内容都首先绘制在内存缓冲区(一个wx. bitmap)上,然后使用相关的wx复制到屏幕上。wx.BufferedDC本身通常与wx. ClientDC相关联。wx.BufferedPaintDC:这是wx.BufferedDC的一个子类,可以在EVT_PAINT()事件处理程序中使用,以实现双缓冲绘图。wx.PostScriptDC:定义了wxWidgets封装的PostScript设备上下文,它可以在任何平台上编写PostScript文件。wx.PrinterDC:提供特定于MSW和Mac的打印机设备上下文,允许使用Windows或Macintosh驱动程序访问任何打印机。wx.ScreenDC:提供一个可以用来在屏幕上绘图的设备上下文,它通常被构造为一个临时堆栈对象来使用。wx.WindowDC:如果应用程序希望在窗口的整个区域(客户端和装饰)上进行绘制,则必须构造wx.WindowDC。它通常被构造为一个临时堆栈对象来使用。wx.ClientDC:主要用于从EVT_PAINT()处理程序外部获取关于窗口的信息。一个典型用途就是获取某个文本字符串的范围,以便为窗口分配足够的大小。wx.PaintDC:如果应用程序希望从EVT_PAINT()事件处理程序中绘制窗口的客户端区域,则必须构造wx.PaintDC。它通常被构造为一个临时堆栈对象来使用。

注意:与窗口相关的设备上下文(例如wx.ClientDC,wx.WindowDC和wx.PaintDC)默认使用窗口字体和颜色,但其他设备上下文类使用系统默认值,因此在使用它们之前必须设置适当的字体和颜色。

三、绘制一条直线

下面我们通过绘制一条简单的直线来演示wx.ClientDC和wx.PaintDC的用法。

我们的第一个例子使用wx.ClientDC在窗口的客户端区域上画一条简单的线。

DrawLine(self, x1, y1, x2, y2)

这个方法从第一个点到第二个点画一条线(不包括第二点)。

绘制一天简单的直线import wxclass SampleDrawLine(wx.Frame):    def __init__(self, *args, **kw):        super(SampleDrawLine, self).__init__(*args, **kw)        self.InitUi()    def InitUi(self):        self.SetTitle("实战wxPython: GDI-画一条简单的直线")        self.SetSize(400, 240)        wx.CallLater(2000, self.DrawLine)        self.Centre()    def DrawLine(self):        dc = wx.ClientDC(self)        dc.DrawLine(50, 60, 190, 60)def main():    app = wx.App()    sample = SampleDrawLine(None)    sample.Show()    app.MainLoop()if __name__ == "__main__":    main()

运行上面的代码,两秒钟过去后,我们在框架窗口上画一条线。

wx.FutureCall(2000, self.DrawLine)

我们在创建窗口之后调用DrawLine()方法。如果在窗口创建时就绘制,我们所有的在客户区的绘制信息将被丢掉。但可以在创建窗口后开始绘图,这就是为什么调用wx.FutureCall()方法的原因。

def DrawLine(self):    dc = wx.ClientDC(self)    dc.DrawLine(50, 60, 190, 60)

创建一个wx.ClientDC设备上下文。唯一的参数是要绘制的窗口。在本例中,它是self,它是对wx.Frame控件的引用。然后调用设备上下文的DrawLine()方法,在窗口上画了一条线。

在上面的例子中,当我们调整窗口的大小时,窗口会重画,这时候直线会消失,因此在窗口需要重新绘制的时候,都需要重新绘制这条线。其解决办法是wx.PaintEvent事件,每当窗口被重新绘制时,将触发该事件,我们在该事件绑定的方法中绘制就可以解决直线消失的问题。

下面的例子展示了如何做到这一点。

#绘制一天简单的直线import wxclass SampleDrawLine(wx.Frame):    def __init__(self, *args, **kw):        super(SampleDrawLine, self).__init__(*args, **kw)        self.InitUi()    def InitUi(self):        self.SetTitle("实战wxPython: GDI-画一条简单的直线")        self.SetSize(400, 240)        self.Bind(wx.EVT_PAINT, self.OnPaint)        self.Centre()    def OnPaint(self, e):        dc = wx.ClientDC(self)        dc.DrawLine(50, 60, 190, 60)def main():    app = wx.App()    sample = SampleDrawLine(None)    sample.Show()    app.MainLoop()if __name__ == "__main__":    main()

绘制同样的一条直线,这次在Paint事件的响应函数里处理。

self.Bind(wx.EVT_PAINT, self.OnPaint)

我们将OnPaint方法绑定到wx.PaintEvent事件。这意味着每次重新绘制窗口时,我们都会调用OnPaint()方法。现在调整窗口的大小(覆盖它,最大化它),这条线将不会消失。

dc = wx.PaintDC(self)

注意,这次使用了wx.PaintDC设备上下文。

图2:绘制一条直线

三、本文知识点

了解wxPython的GDI系统。了解wx.DC及其派生类。使用wx.ClientDC和wx.PaintDC进行绘图。

前一篇:wxPython - 图片相关的类

欢迎关注,评论,收藏,点赞,和转发。

标签: #gdipython