wxPython 多个绘制函数

wxPython multiple draw functions

我是 wxPython 的新手。我有两个生成不同图形视图的函数(在本例中简化为 DrawRect1 和 DrawRect2)。我想使用菜单在这两个视图之间切换。

我见过的大多数示例都将 EVT_PAINT 绑定到一个名为 OnPaint 的函数,但我不明白如何定义可以链接到菜单选项的多个绘图函数。

在下面的代码中,我绘制了所需的矩形,但没有显示背景色,我没有收到任何错误。

我使用的是 ClientDC 而不是 PaintDC,据我所知,这是不同的函数可以绘制到屏幕上的方式,而不是绑定了 EVT_PAINT 的单个函数。

是我代码中的做法有误吗?或者这只是刷新显示的问题?我正在尝试清除面板(通过重新创建它)然后在其上绘图(这不起作用,因为未显示背景颜色)。

import wx


class Mywin(wx.Frame):

    def __init__(self, parent, title):
        super(Mywin, self).__init__(parent, title=title, size=(500, 300))

        self.InitUI()

    def InitUI(self):

        self.panel = wx.Panel(self)
        self.panel.SetBackgroundColour(wx.Colour('RED'))


        self.Centre()
        self.Show(True)

        menuBar = wx.MenuBar()
        RectangleButton = wx.Menu()

        Item1 = RectangleButton.Append(wx.ID_ANY, 'Rectangle 1')
        Item2 = RectangleButton.Append(wx.ID_ANY, 'Rectangle 2')

        menuBar.Append(RectangleButton, 'Rectangles')

        self.SetMenuBar(menuBar)

        self.Bind(wx.EVT_MENU, self.DrawRect1, Item1)
        self.Bind(wx.EVT_MENU, self.DrawRect2, Item2)


    def DrawRect1(self, e):
        self.panel.Destroy()
        self.panel = wx.Panel(self, size=self.GetClientSize())
        self.dc = wx.ClientDC(self.panel)
        self.panel.SetBackgroundColour(wx.Colour('BLUE'))
        self.dc.DrawRectangle(10, 10, 100, 100)

    def DrawRect2(self, e):
        self.panel.Destroy()
        self.panel = wx.Panel(self, size=self.GetClientSize())
        self.dc = wx.ClientDC(self.panel)
        self.panel.SetBackgroundColour(wx.Colour('GREEN'))
        self.dc.DrawRectangle(20, 20, 50, 50)


myApp = wx.App()
Mywin(None,'Drawing demo')
myApp.MainLoop()

在这里使用 wx.ClientDC 是正确的做法,因为您想从菜单命令而不是 wx.Paint 事件中绘制。

我想没必要在每次绘制时都destroy/create面板,所以我从代码中删除了这部分。

另外两点需要注意的是:

1.- 您需要 select wx.CLientDC 的画笔颜色,因为默认情况下画笔颜色将与面板相同,这会导致不可见的矩形。这是通过以下行完成的:self.dc.SetBrush(wx.Brush(wx.Colour('white')))

2.- 我在绘制矩形之前添加了一个 self.Refresh() self.Update() 调用以强制更改面板颜色,然后我使用 wx.ClientDC 对象进行绘制。如果将 self.Refresh() self.Update() 放在方法的末尾,则矩形会消失。

代码如下:

import wx


class Mywin(wx.Frame):

    def __init__(self, parent, title):
        super(Mywin, self).__init__(parent, title=title, size=(500, 300))

        self.InitUI()

    def InitUI(self):

        self.panel = wx.Panel(self)
        self.panel.SetBackgroundColour(wx.Colour('RED'))


        self.Centre()
        self.Show(True)

        menuBar = wx.MenuBar()
        RectangleButton = wx.Menu()

        Item1 = RectangleButton.Append(wx.ID_ANY, 'Rectangle 1')
        Item2 = RectangleButton.Append(wx.ID_ANY, 'Rectangle 2')

        menuBar.Append(RectangleButton, 'Rectangles')

        self.SetMenuBar(menuBar)

        self.Bind(wx.EVT_MENU, self.DrawRect1, Item1)
        self.Bind(wx.EVT_MENU, self.DrawRect2, Item2)


    def DrawRect1(self, e):
        self.panel.SetBackgroundColour(wx.Colour('BLUE'))
        self.Refresh()
        self.Update()
        self.dc = wx.ClientDC(self.panel)
        self.dc.SetBrush(wx.Brush(wx.Colour('white')))
        self.dc.DrawRectangle(10, 10, 100, 100)

    def DrawRect2(self, e):
        self.panel.SetBackgroundColour(wx.Colour('GREEN'))
        self.Refresh()
        self.Update()        
        self.dc = wx.ClientDC(self.panel)
        self.dc.SetBrush(wx.Brush(wx.Colour('white')))
        self.dc.DrawRectangle(20, 20, 50, 50)

myApp = wx.App()
Mywin(None,'Drawing demo')
myApp.MainLoop()