Нужна помощь в работе с self.MemoryDC в wxPython

#python #widget #wxpython #doublebuffered

#python #виджет #wxpython #двойной буфер

Вопрос:

Я пытаюсь создать пользовательский текстовый виджет с двойной буферизацией (чтобы избежать мерцания). Тем не менее, я хотел бы иметь возможность сделать несколько вещей. Тем не менее, я не уверен в точных методах, которые я должен использовать.

Первые два просты, я просто хочу изменить цвет фона и переднего плана.

Итак, более или менее я хочу иметь возможность изменять цвет текста для self.Текст в self.Draw().

Фрагмент:

 self.Text = mdc.DrawText(self.TextString, 10, 0) 
  

Продается в качестве цвета фона (заливки) для self.MemoryDC.

Далее, кто-нибудь знает, как я мог бы сосредоточить self.Текст? Наконец, как мне настроить self.Текст после его создания?

Виджет до сих пор:

 class DynamicText (wx.Panel):
    def __init__(self, par):
        self.Par = par

        wx.Panel.__init__(self, self.Par)


        self.Time = Time(self, func=self.SetTime)



        self.Dim = self.Par.GetClientSize()
        self.SetSize(self.Dim)

        self.Bind(wx.EVT_SIZE, self.Resize)
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.Erase)
        self.Bind(wx.EVT_PAINT, self.Paint)

    def Set (self, text) :
        self.TextString = text

    def SetTime (self, time) :
        self.Set(str(time))
        self.Resize(None)

    def Resize(self, event):

        self.Width, self.Height = self.GetSize()

        bitmap = wx.EmptyBitmap(self.Width, self.Height)

        self.MemoryDC = wx.MemoryDC(bitmap)

        ''' Redraws **self.MemoryDC** '''
        mdc = self.MemoryDC

        ''' Deletes everything from widget. '''
        mdc.Clear()


        fs = 11
        font = wx.Font( fs, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
        mdc.SetFont(font)

        self.Draw()

        self.Refresh()



    def Draw (self) :
        mdc = self.MemoryDC
        self.Text = mdc.DrawText(self.TextString, 10, 0)

    def Erase(self, event):
        ''' Does nothing, as to avoid flicker. '''
        pass

    def Paint(self, event):
        pdc = wx.PaintDC(self)
        w, h = self.MemoryDC.GetSize()
        pdc.Blit(0, 0, w, h, self.MemoryDC, 0, 0)
  

Ответ №1:

Я не понимаю, что вы подразумеваете под настройкой self.Текст после того, как он был создан. Если вы хотите изменить текст после того, как вы его нарисовали — вы не можете. Как только вы перенесли его в DC, он там, и единственный способ изменить это — очистить DC и перерисовать его. В вашем случае, кажется, все, что вам нужно сделать при обновлении текста, это снова вызвать Resize(), принудительно перерисовывая. Обратите внимание, что DrawText() ничего не повторяет, поэтому значение вашего self.Text будет None . Вы определенно не можете использовать это для ссылки на нарисованный текст. 😀

Что касается остального, вот пример метода Draw(), который центрирует текст и окрашивает его в синий цвет:

 def Draw(self) :
    mdc = self.MemoryDC
    dc_width, dc_height = mdc.GetSizeTuple()
    text_width, text_height, descent, externalLeading = mdc.GetFullTextExtent(self.TextString)
    x = (dc_width  - text_width)  / 2
    y = (dc_height - text_height) / 2
    mdc.SetTextForeground('Blue')
    mdc.DrawText(self.TextString, x, y)
  

Комментарии:

1. Да, я имел в виду возможность изменять текст после того, как он был отрисован как configure. Я новичок в wxPython, поэтому я все еще пытаюсь разобраться в нем. Насколько я понимаю, wx.MemoryDC() можно заставить функционировать как виджет Tkinter Canvas. Вы можете настроить текст для этого конкретного виджета без необходимости его перерисовывать. Спасибо!