是否可以在TextCtrl上绘图?如果是这样,怎么样?

时间:2014-03-23 14:38:15

标签: wxpython wxwidgets wxtextctrl wxperl

我试图用一些线条图来详细说明一个TextCtrl:我想在文本,旁边,线条之间绘制简单的东西等等。我正在接近绘图在Wx中我曾经在WxPanels上做过:使用DCs:$ 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);
};

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

这种理解对我来说意味着:为了能够绘画,我需要访问已经准备好的/绘制的直流电,这样我才能开始绘制它。对?一般来说,在WxPerl中这是可能的吗?在我上面的函数中,我在控件绘制文本之前做了我的绘画,当我取消注释Skip()时,我认为线条消失的原因 - 因为控件然后清除并重绘直流。

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

P.S。

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

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

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

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

3 个答案:

答案 0 :(得分:3)

这不是您想要听到的答案,但您无法在本机控件上绘图(而wxTextCtrl就是这样)。它已经吸引了它,你不能干扰它的绘图逻辑,特别是考虑到它在不同平台下的不同。因此,虽然你有时可以让它工作(特别是在MSW,只要有可能的东西,即你完全可以自由地用许多不同的方式射击自己),这是保证在所有平台下工作,你根本不应该这样做。

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

答案 1 :(得分:0)

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

对于它的价值,这里是如何使用C ++

wxTextCtrl::OnPaint()

答案 2 :(得分: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()