2014-01-07 7 views
0

Я хочу нарисовать прямоугольник в верхней части растрового изображения движением мыши. Но прямоугольник отображается под растровым изображением. Следующий мой код.Как нарисовать прямоугольник на верхнем уровне

#!/usr/bin/env python 

import sys, os 
import wx 
import wx.lib.scrolledpanel as scrolled 

class ImgPanel(scrolled.ScrolledPanel): 
    def __init__(self, parent): 
     super(ImgPanel, self).__init__(parent, 
             style = wx.SUNKEN_BORDER) 

     self.bitmap=wx.StaticBitmap(parent=self) 
     image = wx.Bitmap('image.jpg') 
     self.bitmap.SetBitmap(image) 

     self.imgSizer = wx.BoxSizer(wx.VERTICAL)   
     self.imgSizer.Add(self.bitmap, 1, wx.EXPAND) 
     self.SetSizer(self.imgSizer) 

     self.SetAutoLayout(1) 
     self.SetupScrolling()  
     self.Bind(wx.EVT_PAINT, self.OnPaint) 
     self.bitmap.Bind(wx.EVT_MOTION, self.OnMove) 
     self.bitmap.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) 
     self.bitmap.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) 
     self.IsRectReady = False 
     self.newRectPara=[0,0,0,0] 


    def OnMove(self,evt): 
     if True == self.IsRectReady: 
      self.newRectPara[2]=evt.GetPosition()[0]-self.newRectPara[0]+1 
      self.newRectPara[3]=evt.GetPosition()[1]-self.newRectPara[1]+1 
      self.Refresh() 

    def OnLeftDown(self, evt): 
     self.IsRectReady=True 
     self.newRectPara[0]=evt.GetPosition()[0] 
     self.newRectPara[1]=evt.GetPosition()[1] 


    def OnLeftUp(self, evt): 
     self.IsRectReady=False 

    def OnPaint(self, evt):   
     dc=wx.PaintDC(self) 
     dc.Clear() 
     if self.IsRectReady: 
      dc.DrawRectangle(self.newRectPara[0], self.newRectPara[1], 
          self.newRectPara[2], self.newRectPara[3]) 

class WinFrame(wx.Frame): 
    def __init__(self, parent, title, width, height): 
     super(WinFrame, self).__init__(parent, 
             title=title, 
             size=(width, height)) 

     self.imgPanel = ImgPanel(self) 
     self.frameSizer = wx.BoxSizer(wx.HORIZONTAL)   
     self.frameSizer.Add(self.imgPanel, 1, wx.EXPAND)   
     self.SetAutoLayout(True) 
     self.SetSizer(self.frameSizer) 
     self.Layout()  

     self.Centre() 
     self.Show(True)   


class MyApp(wx.App): 
    def __init__(self, width, height): 
     super(MyApp, self).__init__(0) 

     self.width = width 
     self.height = height 

    def createFrame(self): 
     self.frame = WinFrame(None, "test", self.width, self.height) 
     self.SetTopWindow(self.frame)  

def main(): 
    app = MyApp(640, 480) 
    app.createFrame() 
    app.MainLoop() 

if "__main__" == __name__ : 
    main() 
+1

В других рамках я всегда использовал контейнер, который может содержать изображение, а также рисованный прямоугольник (например, холст). Вы не можете использовать такую ​​вещь? AFAICS, что вещь 'DC', вероятно, всегда находится под изображением, поэтому ваш подход не будет работать. – Alfe

+0

Сначала я использую 'floatcanvas'. Но я не могу найти хорошие учебники. Я использую виджет 'staticbitmap' в прокручиваемой панели для создания прокручиваемой строки. Я не знаю другого способа рендеринга большого изображения, в то время как может генерировать прокручиваемый бар. – Samuel

ответ

2

Поскольку wx.StaticBitmap отдельный (ребенок) окно всегда будет на вершине своего родителя, ImgPanel. Другими словами, любой рисунок, сделанный на ImgPanel, всегда будет отображаться или под видовым изображением растрового изображения. Если вы хотите, чтобы изображение и ваш рисунок были объединены, вместо использования wx.StaticBitmap вы должны добавить рисование растрового изображения в ваш обработчик EVT_PAINT.

+0

Вы имели в виду, что я должен использовать 'DC.DrawBitmap' вместо' StaticBitmap' widget. Я пробовал этот метод. Но если изображение больше, чем панель. Он не может создать прокручиваемую строку. – Samuel

+1

Используйте wx.ScrolledWindow, установите виртуальный размер окна, чтобы он был достаточно большим, чтобы отобразить все изображение, и установите скорость прокрутки, чтобы установить приращения, которые будут использовать полосы прокрутки. – RobinDunn

+0

У меня две панели в рамке. Одна панель предназначена для изображения. Поэтому я должен использовать одну панель и одно прокручиваемое окно в одном кадре. Правильно? – Samuel

Смежные вопросы