You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

wxPython OGL点击按钮绘制线条不即时显示问题求助

wxPython OGL按钮事件中添加线条无法即时显示的原因及解决方法

问题代码

import wx
import wx.lib.ogl as ogl


class MyPen:
    def __init__(self, color, width, style):
        self.my_pen = wx.Pen()
        wx.Pen.SetColour(self.my_pen, color)
        wx.Pen.SetWidth(self.my_pen, width)
        wx.Pen.SetStyle(self.my_pen, style)


class EdgeShape(ogl.LineShape):
    def __init__(self, arrow, x1, y1, x2, y2, selected, canvas):
        super().__init__()
        if arrow:
            self.AddArrow(ogl.ARROW_ARROW)

        self.MakeLineControlPoints(2)
        self.SetEnds(x1, y1, x2, y2)
        self.pen = MyPen(wx.Colour(0, 0, 0), 2, wx.PENSTYLE_SOLID).my_pen
        self.brush = wx.BLACK_BRUSH
        self.SetPen(self.pen)
        self.SetBrush(self.brush)
        self.SetCanvas(canvas)
        canvas.diagram.AddShape(self)
        self.Show(True)


class GraphCanvas(ogl.ShapeCanvas):
    def __init__(self, parent):
        super().__init__(parent)
        maxWidth = 1000
        maxHeight = 1000
        self.SetScrollbars(20, 20, maxWidth // 20, maxHeight // 20)
        self.SetBackgroundColour("LIGHT BLUE")
        self.diagram = ogl.Diagram()
        self.SetDiagram(self.diagram)
        self.diagram.SetCanvas(self)


class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(None, title="wxPython OGL Clickable Shapes")

        add_edge_btn = wx.Button(self, label="Add Edge")
        add_node_btn = wx.Button(self, label="Add Node")

        self.graph_canvas = GraphCanvas(self)

        main_sizer = wx.BoxSizer(wx.HORIZONTAL)
        button_sizer = wx.BoxSizer(wx.VERTICAL)
        button_sizer.Add(add_edge_btn, flag=wx.CENTER)
        button_sizer.Add(add_node_btn, flag=wx.CENTER)
        main_sizer.Add(button_sizer, proportion=1, flag=wx.EXPAND)
        main_sizer.Add(self.graph_canvas, proportion=3, flag=wx.EXPAND)
        self.SetSizer(main_sizer)
        add_edge_btn.Bind(wx.EVT_BUTTON, self.add_edge)
        add_node_btn.Bind(wx.EVT_BUTTON, self.add_node)
        self.Show()

    def add_edge(self, event):
        edge_shape = EdgeShape(False, 10, 10, 100, 100, False, self.graph_canvas)

    def add_node(self, event):
        pass


if __name__ == '__main__':
    app = wx.App(False)
    ogl.OGLInitialize()
    frame = MyFrame()
    app.MainLoop()

问题描述

点击Add Edge按钮后创建的线条不会立即显示,只有拖动滚动条后才会出现;但如果将创建EdgeShape的代码移至MyFrame类的初始化方法中,线条则能正常即时显示。

原因分析

  • 在MyFrame初始化方法中创建线条时,后续调用self.Show()会触发整个窗口的重绘流程,ShapeCanvas作为子控件会跟着完成重绘,所以线条能即时显示。
  • 在按钮事件函数中创建线条时,只是将线条添加到了画布的图形容器,但没有主动触发画布的重绘操作。滚动条拖动时会触发画布的重绘事件,这时线条才会被渲染出来。

解决方法

在按钮事件的add_edge函数中添加画布的重绘调用即可:

def add_edge(self, event):
    edge_shape = EdgeShape(False, 10, 10, 100, 100, False, self.graph_canvas)
    self.graph_canvas.Refresh()  # 触发画布重绘
    self.graph_canvas.Update()   # 立即执行重绘,确保即时显示

也可以在EdgeShape的__init__方法末尾添加画布重绘:

class EdgeShape(ogl.LineShape):
    def __init__(self, arrow, x1, y1, x2, y2, selected, canvas):
        # ... 原有代码 ...
        self.Show(True)
        canvas.Refresh()

内容的提问来源于stack exchange,提问作者Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 08:43:21