1

我正在尝试用一些线条图来详细说明 TextCtrl:我想在文本上、在文本旁边、在行之间等绘制简单的东西。我正在像以前在 WxPanels 上所做的那样在 Wx 中进行绘图: 带 DC: $dc->DrawLine(15, 15, 120, 120); 等等

到目前为止,我正在这样做:在派生自 TextCtrl 的类中,我捕获 EVT_PAINT 并实现我自己的 OnPaint 函数:

sub new {
     my $class  = shift;
     my $parent = shift;

     my $self = $class->SUPER::new( $parent, -1, '', wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);

     EVT_PAINT($self, \&OnPaint );

     return $self;
}

sub OnPaint {
    print"OnPaint: @_ \n";

    # @ravenspoint: this is there I would call the base's paint method
    # first, right? But how??

    my $linesCnt = $_[0]->GetNumberOfLines();

        my $dc = Wx::PaintDC->new($_[0]);
        $dc->DrawLine(
            15, 15,
            120, 120
        );

    # commented out as the base class' paint method will follow,
    # erasing what we've just drawn
    #   $_[1]->Skip(1);
};

现在,问题是:当我让绘制事件向上传播或不传播时,控件中的线条或文本都被绘制了。对于任何 Wx 大师来说,这可能是显而易见的,但对我来说,并非如此。据我了解,TextCtrl 是 WxWindow 的集合体,是一种将文本绘制到其中的低级方式,带有 dc、DrawText() 和顶部的一些便利功能,用于设置插入符号等。

这种理解对我来说意味着:为了能够画画,我需要访问已经准备好的/绘制的 dc,这样我才能继续在上面画画。正确的?通常,在 WxPerl 中,这可能吗?在我上面的函数中,我在控件绘制文本之前进行绘制,这就是我认为当我取消注释 Skip() 时线条消失的原因 - 因为控件然后清除并重绘 dc。

在 TextCtrl 完成所有绘制之后,有没有办法进入循环?

附言

Plain TextCtrl 似乎是通过在大多数平台上调用本机文本条目来实现的,尽管文档没有提到这一点。

我在 Kephra 和 Padre 中进行了挖掘,它们都显示了一个“右边距指示器”,一条通常为灰色的细垂直线,绘制在文本区域上。他们是如何做到的呢?惊喜:它们是 Wx::Scintilla 或较旧的 Wx::StyledTextCtrl 的子类,它们都提供了 SetEdgeColumn() 方法来触发它。

问自己是否重新实现我自己的文本小部件是访问/挂钩到 DC 上的文本绘制的唯一方法。(难以置信地摇头)

修补 *EVT_ERASE_BACKGROUND* 和 RichtTextCtrl 的PaintBackground()没有成功(好吧,经过几分钟的黑客攻击)。

4

3 回答 3

3

这不是您想听到的答案,但您不能使用本机控件(并且wxTextCtrl就是这样)。它已经自己绘制了,你不能干涉它的绘制逻辑,特别是考虑到它在不同平台下是不同的。因此,虽然您有时可以使其工作(尤其是在 MSW 下,一切皆有可能,即您可以完全自由地以多种不同方式射击自己的脚),但这并不能保证在所有平台下都能工作,您真的不应该'根本不这样做。

如果您想要一些 不提供的高级功能wxTextCtrl,您可能应该查看wxRichTextCtrl。它也完全在 wxWidgets 本身中实现,即不是原生的,所以你可以在它上面绘制。

于 2014-03-24T13:15:08.113 回答
0

我正在尝试按照 VZ 的建议行事。下面是一个用于创建 RichTextCtrl 并在其上画一条线的最小程序。相反,它只绘制一个 RichTextCtrl 框。如果我注释掉以“self.rtc =”开头的行,它只会绘制该行,而不是 RichTextContrl。

# sources:
  # http://wiki.wxpython.org/VerySimpleDrawing
  # https://github.com/wxWidgets/wxPython/blob/master/demo/RichTextCtrl.py

import wx
import wx.richtext as rt

class DrawPanel(wx.Frame):
    def __init__(self, *args, **kw):
        wx.Frame.__init__(self, *args, **kw)
        self.rtc = rt.RichTextCtrl(self,style=wx.VSCROLL|wx.HSCROLL|wx.NO_BORDER)
        self.Bind(wx.EVT_PAINT, self.OnPaint)

    def OnPaint(self, event=None):
        dc = wx.PaintDC(self)
        dc.Clear()
        dc.SetPen(wx.Pen(wx.BLACK, 2))
        dc.DrawLine(0, 0, 50, 50)

app = wx.App(False)
frame = DrawPanel(None)
frame.Show()
app.MainLoop()
于 2015-02-21T22:11:27.347 回答
0

在覆盖基类绘制方法的函数中,在您自己的代码之前调用基类绘制方法。

对于它的价值,这里是如何用 C++ 做到这一点

wxTextCtrl::OnPaint()
于 2014-03-23T17:34:26.277 回答