我对python很新,我正在尝试使用cairo和wxpython编写一个简单的程序。我习惯使用gtk和C的cairo,但我发现自己很困惑。
我用以下代码构建了一个简单的ui:
import wx
class Frame(wx.Frame):
def __init__(self, *args, **kwargs):
super(Frame, self).__init__(*args, **kwargs)
self.InitUI()
def InitUI(self):
#----------------------------------------------------
# Build menu bar and submenus
menubar = wx.MenuBar()
# file menu containing quit menu item
fileMenu = wx.Menu()
quit_item = wx.MenuItem(fileMenu, wx.ID_EXIT, '&Quit\tCtrl+W')
fileMenu.AppendItem(quit_item)
self.Bind(wx.EVT_MENU, self.OnQuit, quit_item)
menubar.Append(fileMenu, '&File')
# help menu containing about menu item
helpMenu = wx.Menu()
about_item = wx.MenuItem(helpMenu, wx.ID_ABOUT, '&About\tCtrl+A')
helpMenu.AppendItem(about_item)
self.Bind(wx.EVT_MENU, self.OnAboutBox, about_item)
menubar.Append(helpMenu, '&Help')
self.SetMenuBar(menubar)
#----------------------------------------------------
# Build window layout
panel = wx.Panel(self)
#panel.SetBackgroundColour('yellow')
vbox = wx.BoxSizer(wx.VERTICAL)
panel.SetSizer(vbox)
midPan = wx.Panel(panel)
#midPan.SetBackgroundColour('blue')
hbox = wx.BoxSizer(wx.HORIZONTAL)
vbox.Add(midPan, 1, wx.EXPAND | wx.ALL, 12)
midPan.SetSizer(hbox)
smallPan = wx.Panel(panel)
#smallPan.SetBackgroundColour('red')
hbox2 = wx.BoxSizer(wx.HORIZONTAL)
vbox.Add(smallPan, 0, wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT|wx.BOTTOM, 12)
smallPan.SetSizer(hbox2)
#----------------------------------------------------
# Place buttons in correct box corresponding with panel
close_button = wx.Button(smallPan, wx.ID_CLOSE)
self.Bind(wx.EVT_BUTTON, self.OnQuit, close_button)
hbox2.Add(close_button)
#----------------------------------------------------
# Set window properties
self.SetSize((1600, 1200))
self.SetTitle('PROGRAM NAME')
self.Centre()
def OnQuit(self, e):
self.Close()
def main():
ex = wx.App()
f = Frame(None)
f.Show(True)
ex.MainLoop()
if __name__ == '__main__':
main()
我希望能够在名为midPan的面板中绘图。如何添加OnDraw函数并链接信号处理程序?
我非常感谢帮助。
答案 0 :(得分:1)
如果你习惯于程序编程那么混乱
很自然。 Python是一种OOP语言,在OOP中编码
语言是完全不同的。我已经清理并更新了
提供的例子。用作绘图区域的面板
涂上三个彩色矩形。你没有提供
因此,我有OnAboutBox()
方法的实现
注释掉了这条线。
#!/usr/bin/python
import wx
import wx.lib.wxcairo
import cairo
class DrawingArea(wx.Panel):
def __init__ (self , *args , **kw):
super(DrawingArea , self).__init__ (*args , **kw)
self.SetDoubleBuffered(True)
self.Bind(wx.EVT_PAINT, self.OnPaint)
def OnPaint(self, e):
dc = wx.PaintDC(self)
cr = wx.lib.wxcairo.ContextFromDC(dc)
self.DoDrawing(cr)
def DoDrawing(self, cr):
cr.set_source_rgb (0.2 , 0.23 , 0.9)
cr.rectangle(10 , 15, 90, 60)
cr.fill()
cr.set_source_rgb(0.9 , 0.1 , 0.1)
cr.rectangle(130 , 15, 90, 60)
cr.fill()
cr.set_source_rgb(0.4 , 0.9 , 0.4)
cr.rectangle(250 , 15, 90, 60)
cr.fill()
class Frame(wx.Frame):
def __init__(self, *args, **kwargs):
super(Frame, self).__init__(*args, **kwargs)
self.InitUI()
def InitUI(self):
#----------------------------------------------------
# Build menu bar and submenus
menubar = wx.MenuBar()
# file menu containing quit menu item
fileMenu = wx.Menu()
quit_item = wx.MenuItem(fileMenu, wx.ID_EXIT, '&Quit\tCtrl+W')
fileMenu.AppendItem(quit_item)
self.Bind(wx.EVT_MENU, self.OnQuit, quit_item)
menubar.Append(fileMenu, '&File')
# help menu containing about menu item
helpMenu = wx.Menu()
about_item = wx.MenuItem(helpMenu, wx.ID_ABOUT, '&About\tCtrl+A')
helpMenu.AppendItem(about_item)
#~ self.Bind(wx.EVT_MENU, self.OnAboutBox, about_item)
menubar.Append(helpMenu, '&Help')
self.SetMenuBar(menubar)
#----------------------------------------------------
# Build window layout
panel = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
panel.SetSizer(vbox)
midPan = DrawingArea(panel)
vbox.Add(midPan, 1, wx.EXPAND | wx.ALL, 12)
smallPan = wx.Panel(panel)
hbox2 = wx.BoxSizer(wx.HORIZONTAL)
vbox.Add(smallPan, 1, wx.EXPAND|wx.ALL, 12)
smallPan.SetSizer(hbox2)
#----------------------------------------------------
# Place buttons in correct box corresponding with panel
close_button = wx.Button(smallPan, wx.ID_CLOSE)
self.Bind(wx.EVT_BUTTON, self.OnQuit, close_button)
hbox2.Add(close_button)
#----------------------------------------------------
# Set window properties
#~ self.SetSize((1600, 1200))
self.SetSize((400, 250))
#~ self.Maximize()
self.SetTitle('PROGRAM NAME')
self.Centre()
def OnQuit(self, e):
self.Close()
def main():
ex = wx.App()
f = Frame(None)
f.Show(True)
ex.MainLoop()
if __name__ == '__main__':
main()
为了进行绘图,我们创建了一个自定义类,它将作为一个
绘图区。它继承自wx.Panel
小部件。
class DrawingArea(wx.Panel):
def __init__ (self , *args , **kw):
super(DrawingArea , self).__init__ (*args , **kw)
self.SetDoubleBuffered(True)
self.Bind(wx.EVT_PAINT, self.OnPaint)
...
这是我们用于绘图的自定义类。在构造函数中
我们将paint事件绑定到OnPaint()
方法。
def OnPaint(self, e):
dc = wx.PaintDC(self)
cr = wx.lib.wxcairo.ContextFromDC(dc)
self.DoDrawing(cr)
在OnPaint()
方法中,我们创建了一个cairo绘图
上下文并将实际绘图代码委托给DoDrawing()
方法
midPan = DrawingArea(panel)
vbox.Add(midPan, 1, wx.EXPAND | wx.ALL, 12)
创建绘图区域并将其添加到垂直框中。
#~ self.SetSize((1600, 1200))
self.SetSize((400, 250))
#~ self.Maximize()
最后注意事项:如果您想要显示最大化的窗口,请致电Maximize()
方法。电脑屏幕尺寸不同。
答案 1 :(得分:0)
如Very Simple Drawing示例中所述,使用wx.EVT_PAINT;
将OnPaint绑定添加到midPan:
# (...)
midPan = wx.Panel(panel)
#midPan.SetBackgroundColour('blue')
hbox = wx.BoxSizer(wx.HORIZONTAL)
vbox.Add(midPan, 1, wx.EXPAND | wx.ALL, 12)
midPan.SetSizer(hbox)
# binding here:
midPan.Bind(wx.EVT_PAINT, self.OnPaint)
# (...) rest of code
并定义您的OnPaint代码:
# (...)
def OnQuit(self, e):
self.Close()
# your OnPaint():
def OnPaint(self,event):
dc = wx.PaintDC(event.GetEventObject())
dc.Clear()
# set up your pen
dc.SetPen(wx.Pen("BLACK", 4))
# draw whatever you like
dc.DrawLine(0, 0, 50, 50)
# (...) rest of code