Какой самый простой способ создать фасонное окно в wxPython? - PullRequest
5 голосов
/ 02 февраля 2011

Я хотел бы создать окно простой формы в wxPython.Более или менее я хочу сделать wx-эквивалент Tkinter self.overrideredirect (1) (он избавляется от границы ОС по умолчанию), затем закруглить углы в окне.

1 Ответ

9 голосов
/ 02 февраля 2011

В демонстрациях wxPython есть демонстрация рамочной формы.Я прошу прощения за косвенный источник.Первоначально они пришли в качестве установщика Windows здесь :

исходный код

Вы можете посмотреть на shape_frame_mobile.py или shape_frame.pyкоторые оба вызывают images.py из этого списка для растрового изображения окна примера.Это не точный эквивалент overrideredirect, так как вам нужно будет предоставить изображение, которое будет нарисовано для рамки, но оно все равно может помочь вам сделать нечто подобное.

Важными частями являются функции, которые устанавливают форму окна на основе растрового изображения и обрабатывают событие wx.EVT_PAINT:

def SetWindowShape(self, evt=None):
    r = wx.RegionFromBitmap(self.bmp)
    self.hasShape = self.SetShape(r)

def OnPaint(self, evt):
    dc = wx.PaintDC(self)
    dc.DrawBitmap(self.bmp, 0,0, True)

Редактировать - вот измененный shaped_frame_mobile.py, который загружает.Изображение png, указанное в переменной IMAGE_PATH.Измените это, чтобы указать на ваше изображение:

import wx

# Create a .png image with something drawn on a white background
# and put the path to it here.
IMAGE_PATH = '/python26/projects/shapedwin/image.png'


class ShapedFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Shaped Window",
                style = wx.FRAME_SHAPED | wx.SIMPLE_BORDER )
        self.hasShape = False
        self.delta = wx.Point(0,0)

        # Load the image
        image = wx.Image(IMAGE_PATH, wx.BITMAP_TYPE_PNG)
        image.SetMaskColour(255,255,255)
        image.SetMask(True)            
        self.bmp = wx.BitmapFromImage(image)

        self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight()))
        dc = wx.ClientDC(self)
        dc.DrawBitmap(self.bmp, 0,0, True)
        self.SetWindowShape()
        self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_MOTION, self.OnMouseMove)
        self.Bind(wx.EVT_RIGHT_UP, self.OnExit)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)

    def SetWindowShape(self, evt=None):
        r = wx.RegionFromBitmap(self.bmp)
        self.hasShape = self.SetShape(r)

    def OnDoubleClick(self, evt):
        if self.hasShape:
            self.SetShape(wx.Region())
            self.hasShape = False
        else:
            self.SetWindowShape()

    def OnPaint(self, evt):
        dc = wx.PaintDC(self)
        dc.DrawBitmap(self.bmp, 0,0, True)

    def OnExit(self, evt):
        self.Close()

    def OnLeftDown(self, evt):
        self.CaptureMouse()
        pos = self.ClientToScreen(evt.GetPosition())
        origin = self.GetPosition()
        self.delta = wx.Point(pos.x - origin.x, pos.y - origin.y)

    def OnMouseMove(self, evt):
        if evt.Dragging() and evt.LeftIsDown():
            pos = self.ClientToScreen(evt.GetPosition())
            newPos = (pos.x - self.delta.x, pos.y - self.delta.y)
            self.Move(newPos)

    def OnLeftUp(self, evt):
        if self.HasCapture():
            self.ReleaseMouse()



if __name__ == '__main__':
    app = wx.PySimpleApp()
    ShapedFrame().Show()
    app.MainLoop()
...