Как проще всего создать фигурное окно в wxPython?

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


person rectangletangle    schedule 02.02.2011    source источник


Ответы (1)


В демонстрациях 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()
person robots.jpg    schedule 02.02.2011
comment
Спасибо, хотя он ссылается на модуль изображений. Я не совсем уверен, что это за модуль. У вас есть какие-нибудь подсказки? - person rectangletangle; 03.02.2011
comment
Это файл images.py из исходной ссылки выше. Вы можете либо поместить его в тот же каталог, что и другие, либо избавиться от import images и загрузить собственное растровое изображение вместо строки images.getVippiBitmap(). Я не знаю, почему демонстрация использует модуль python для предоставления изображения. - person robots.jpg; 03.02.2011
comment
@ Anteater7171 Добавил измененный код в мой ответ. Легче показать, чем объяснить. - person robots.jpg; 03.02.2011
comment
отличный ответ, к вашему сведению wx.RegionFromBitmap был заменен на wx.Region, а wx.BitmapFromImage заменен на wx.Bitmap - person user2682863; 23.03.2017