wxpython - 用 wxpython cairo 绘图感到困惑;wx.BufferedPaintDC 使笔触消失
问题描述
我对 wxpython 和 cairo 比较陌生,请原谅任何初学者的错误。
在使用 wxpython 和 cairo 绘制矩形时,有时会显示边框(笔划),有时不取决于ctx.set_line_width()
. 当它不显示时,我在 python 控制台(使用 pycharm)中收到以下消息:
_cairo_win32_display_surface_flush:操作成功完成。
控制台消息似乎是由 .stroke() 命令生成的。
如果我不检查双缓冲并使用,dc = wx.PaintDC(self)
那么边框会如您所料那样出现。但是,在复杂的绘图上,这不会导致闪烁问题吗?
问题:
- 在复杂的图纸上,是否使用
wx.PaintDC()
了正确的方法? - 有没有一种使用方式
wx.BufferedPaintDC()
,线条按预期显示? - 控制台消息是什么意思?("_cairo_win32_display_surface_flush: 操作成功完成")
我对此感到非常困惑,因此将不胜感激。
在 Windows 上使用 Python 3.8、wxpython 4.1 和 cairo (cairocffi) 进行编码。
我的绘画事件代码是:
def on_paint(self, event):
if self.IsDoubleBuffered():
dc = wx.PaintDC(self)
else:
dc = wx.BufferedPaintDC(self)
dc.SetBackground(wx.WHITE_BRUSH)
dc.Clear()
w, h = self.GetClientSize()
ctx = wxcairo.ContextFromDC(dc)
# draw stuff
ctx.set_source_rgb(0.65, 0.65, 0.65)
ctx.rectangle(25, 25, w-50, h-50)
ctx.fill_preserve()
ctx.set_source_rgb(0.1, 0.1, 0.1)
ctx.set_line_width(1) # width of 10 works, width of 1 doesn't
ctx.stroke()
简化的演示代码:
import wx
import wx.lib.wxcairo as wxcairo
class MyPanel(wx.Panel):
def __init__(self, parent, *args, **kwargs):
super(MyPanel, self).__init__(parent, *args, **kwargs)
self.Bind(wx.EVT_SIZE, self.on_resize)
self.Bind(wx.EVT_PAINT, self.on_paint)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.on_erase_bkground)
def on_erase_bkground(self, event):
pass
def on_resize(self, event):
self.Refresh()
self.Layout()
def on_paint(self, event):
if self.IsDoubleBuffered(): # returns false
dc = wx.PaintDC(self)
else:
dc = wx.BufferedPaintDC(self)
# dc = wx.PaintDC(self) # works as anticipated with thin line widths
dc.SetBackground(wx.WHITE_BRUSH)
dc.Clear()
w, h = self.GetClientSize()
ctx = wxcairo.ContextFromDC(dc)
# draw stuff
ctx.set_source_rgb(0.65, 0.65, 0.65)
ctx.rectangle(25, 25, w-50, h-50)
ctx.fill_preserve()
ctx.set_source_rgb(0.1, 0.1, 0.1)
ctx.set_line_width(1) # width of 10 works, width of 1 doesn't
ctx.stroke() # console message generated by this line
class MyFrame(wx.Frame):
def __init__(self, parent, title):
super(MyFrame, self).__init__(None, title=title, size=(600, 400))
# simple layout
panel = MyPanel(self)
sizer = wx.BoxSizer()
sizer.Add(panel, 1, wx.EXPAND)
self.SetSizer(sizer)
# display
self.Center()
self.Show()
if __name__ == '__main__':
app = wx.App()
frame = MyFrame(None, 'WXPython demo')
app.MainLoop()
解决方案
推荐阅读
- aerospike - 将大数据对象写入 AerospikeDB 的最佳方式是什么?
- c# - .net core 3.1 将 CommandManager 类插入类库项目
- c++ - qt c ++中3级(非均匀和非分形)的B样条
- html - 设置宽度等于高度
- azure - 使用服务主体对 Azure 函数应用进行身份验证的正确方法是什么?
- c - 如何使用 Asio 库生成变量?
- python-3.x - 编写 Keras 模型类
- arrays - 如何在数组中返回多个值 - Excel VBA
- microsoft-teams - 在 SSL 证书更新后,Microsoft Teams 似乎不会向服务器发送机器人请求
- java - 带有 MockMVC 的 Junit - 错误 - java.lang.IllegalArgumentException:实体不能为空