RendererNative
RendererNative是一个包含一个封装了绘制原生态UI组件功能的集合。它允许在一个DC中绘制,不需要知道它是如何运行的任何细节。当需要创建保持平台自己窗口部件原生外观和感觉的通用窗口部件时,这是非常强大和有用的类。
示例演示
定制一个按钮,使用RendererNative单实例根据鼠标的位置和状态来绘制外观,外观看起来是原生的。
#-*-coding: UTF-8 -*-
#------------------------------------------------------
#Purpose: nothing....
#Author: 阿Bin先生
#Created: 2017年5月29日
#------------------------------------------------------
import wx
class DropArrowButton(wx.PyControl):
def __init__(self, parent, id=wx.ID_ANY,
label="", pos=wx.DefaultPosition,
size=wx.DefaultSize, style=0,
validator=wx.DefaultValidator,
name="DropArrowButton"):
style |= wx.BORDER_NONE
super(DropArrowButton, self).__init__(parent, id,
pos, size,
style,
validator, name)
# Attributes
self._label = label
self._state = 0
# Event Handlers
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
self.Bind(wx.EVT_LEAVE_WINDOW,
lambda event:
self.SetState(0))
self.Bind(wx.EVT_ENTER_WINDOW,
lambda event:
self.SetState(wx.CONTROL_CURRENT))
self.Bind(wx.EVT_PAINT, self.OnPaint)
def DoGetBestSize(self):
size = self.GetTextExtent(self._label)
size = (size[0]+16, size[1]+16) # Drop Arrow
size = (size[0]+8, size[1]+4) # Padding
self.CacheBestSize(size)
return size
def OnLeftDown(self, event):
"""Show the drop menu"""
self.SetState(wx.CONTROL_PRESSED)
def OnLeftUp(self, event):
"""Send a button click event"""
if self._state != wx.CONTROL_PRESSED:
return
self.SetState(wx.CONTROL_CURRENT)
def OnPaint(self, event):
"""Draw the Conrol"""
dc = wx.PaintDC(self)
gc = wx.GCDC(dc) # AA text
# Get the renderer singleton
render = wx.RendererNative.Get()
# Get the working rectangle we can draw in
rect = self.GetClientRect()
# Draw the button
render.DrawPushButton(self, gc, rect, self._state)
# Draw the label on the button
lblrect = wx.Rect(rect.x+4, rect.y+2,
rect.width-24, rect.height-4)
gc.DrawLabel(self._label, lblrect, wx.ALIGN_CENTER)
# Draw drop arrow
droprect = wx.Rect((rect.x+rect.width)-20,
rect.y+2, 16, rect.height-4)
state = self._state
if state != wx.CONTROL_PRESSED:
state = wx.CONTROL_CURRENT
render.DrawDropArrow(self, gc, droprect, state)
def SetState(self, state):
self._state = state
self.Refresh()
class MyFrame(wx.Frame):
def __init__(self, parent, *args, **kwargs):
super(MyFrame, self).__init__(parent, *args, **kwargs)
# Attributes
self.Panel = wx.Panel(self)
box = DropArrowButton(self.Panel, -1, "RendererNative", pos = [10, 10])
box.SetSize([200, 100])
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame(None, title="RendererNative",size = [500, 500])
self.SetTopWindow(self.frame)
self.frame.Show()
return True
if __name__ == "__main__":
app = MyApp(False)
app.MainLoop()
运行结果:
代码分析:
在OnPaint方法中,我们得到RendererNative单实例的引用,DrawPushButton绘制一个原生的按钮,DrawLabel绘制按钮的标签,DrawDropArrow绘制按钮的右侧箭头。同时绘制时会传入控件的状态:0表示默认状态,CONTROL_CURRENT表示悬停状态,CONTROL_PRESSED表示按下状态。
绘制方法
以下是RendererNative的绘制方法。所有的方法都有相同的前四个参数:window, DC, rect和flags。
控制标记
以下标记可以作为bitmask的一部分传递给绘制方法flags参数。没有传递任何标记或者传递0给flags参数,表示控件以默认状态绘制。