如何在wxpython中显示wx.DC的CrossHair?

时间:2013-09-22 08:04:43

标签: wxpython

我想在图像上显示一个十字准线。以下是代码:

# -*- coding: utf-8 -*-

import wx

class Locator(wx.Frame):
    def __init__(self, title, size, style):
        super(Locator, self).__init__(parent = None, id = -1,
                                        title = title, size = size, style = style)

        self.panel = wx.Panel(self)

        self.menu = wx.MenuBar()
        self.SetMenuBar(self.menu)

        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.imgbox = wx.BoxSizer(wx.HORIZONTAL)
        self.img = wx.Image('test.jpg')
        self.imgbmp = wx.StaticBitmap(self.panel,
                                        bitmap = wx.BitmapFromImage(self.img),
                                        size = (1325, 614))

        self.panel.SetSizer(self.vbox)
        self.vbox.Add(self.imgbox, flag = wx.ALIGN_CENTER)
        self.imgbox.Add(self.imgbmp)
        self.imgbmp.Bind(wx.EVT_MOTION, self.OnMouseMove)

        self.Show()

    def OnMouseMove(self, e):
        (x, y) = e.GetPosition()
        dc = wx.ClientDC(self.imgbmp) # probelm here!
        dc.Clear()
        dc.SetPen(wx.Pen(wx.Color(0, 0, 0), 1, wx.DOT))
        dc.CrossHair(x, y)

if __name__ == '__main__':
    app = wx.App()
    Locator('Locator',
                size = (1350, 700),
                style = wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX)
    app.MainLoop()

问题是,我不知道哪个对象是wx.ClientDC的参数。当我以self作为参数时,test.jpg正确显示,但没有十字准线。 self.imgbox作为参数,发生错误:

Traceback (most recent call last):
      File "tmp.py", line 50, in OnMouseMove
        dc = wx.ClientDC(self.imgbox)
      File "C:\Users\songsong\AppData\Local\Enthought\Canopy\User\lib\site-packages\wx\_gdi.py", line 4774, in __init__
        _gdi_.ClientDC_swiginit(self,_gdi_.new_ClientDC(*args, **kwargs))
    TypeError: in method 'new_ClientDC', expected argument 1 of type 'wxWindow *'

self.imgbmp为参数,没有test.jpg但是十字准线出现了。

1 个答案:

答案 0 :(得分:1)

我花了一些时间来恢复我对wxPython的熟练程度,但是我们走了。这种方法非常简单,但您不应该尝试同时执行这两种方法 - 获取鼠标位置并绘制十字准线 - 只需一步。

  1. 首先,获取鼠标位置并保存。然后触发重新绘制。
  2. 第二,听取重绘事件,获得DC 然后继续绘制图像,然后在顶部绘制十字准线。
  3. 我缩短了您的示例代码,以便您更轻松地发现最重要的更改:

    # -*- coding: utf-8 -*-
    
    import wx
    
    class Locator(wx.Frame):
        def __init__(self, *args, **kwargs):
            wx.Frame.__init__(self, *args, **kwargs)
            vbox = wx.BoxSizer(wx.VERTICAL)
            self.SetSizer(vbox)
            self.panel = MyPanel(self)
            vbox.Add(self.panel, 2, wx.EXPAND)
            self.Show()
    
    class MyPanel(wx.Panel):
        def __init__(self, *args, **kwargs):
            wx.Panel.__init__(self, *args, **kwargs)
            self.img = wx.Image('test.jpg')
            self.bmp = wx.BitmapFromImage(self.img)
            self.Bind(wx.EVT_MOTION, self.OnMouseMove)
            self.Bind(wx.EVT_PAINT, self.OnPaint)
            self.coordinates = (0, 0)
    
        def OnMouseMove(self, e):
            self.coordinates = e.GetPosition()
            self.Refresh()
    
        def OnPaint(self, e):
            dc = wx.PaintDC(self)
            dc.DrawBitmap(self.bmp, 0, 0, False)
            dc.SetPen(wx.Pen(wx.Color(0, 0, 0), 1, wx.DOT))
            dc.CrossHair(self.coordinates[0], self.coordinates[1])
    
    if __name__ == '__main__':
        app = wx.App()
        Locator(None, -1, title='Locator')
        app.MainLoop()