使用DC动态绘制wx.BitMap按钮?

时间:2010-09-17 05:47:32

标签: python wxpython

我现在能够做到这一点,以完成我想要的大部分工作。它根据文本文件中的线条绘制按钮,并处理不同按钮状态的外观。现在真正绊倒的是当self.input写入文本文件时,我不知道如何根据新文本重新绘制所有内容以添加或更新按钮。我已经尝试UpdateRefreshShow (False)然后Show(True),我感到难过。

import wx
import mmap
import re

class pt:
    with open('note.txt', "r+") as Note:
        buf = mmap.mmap(Note.fileno(), 0)
        TL = 0
        readline = buf.readline
        while readline():
            TL += 1
    Note.closed

class MainWindow(wx.Frame):

    def __init__(self, parent, title):
        w, h = wx.GetDisplaySize()
        x = w * 0
        y = h - bdepth

        wx.Frame.__init__(self, parent, title = title, pos = (x, y), size = (200,bdepth), style = wx.STAY_ON_TOP)

        self.input = wx.TextCtrl(self, -1, "", (6, pt.TL * 64 + 4), (184, 24))
        self.Bind(wx.EVT_TEXT_ENTER, self.OnEnter, self.input)

        self.__DoButtons()            

        self.Show(True)

    def __DoButtons(self):

        Note = open('note.txt', "r+")

        for i, line in enumerate(Note):

            strip = line.rstrip()
            todo = strip.lstrip('!')

            self.check = re.match('!', strip)
            self.priority = re.search('(\!$)', strip)

            checkmark = wx.Image('check.bmp', wx.BITMAP_TYPE_BMP)
            bullet = wx.Image('bullet.bmp', wx.BITMAP_TYPE_BMP)
            exclaim = wx.Image('exclaim.bmp', wx.BITMAP_TYPE_BMP)

            solid = wx.EmptyBitmap(200,64,-1)
            dc = wx.MemoryDC()
            dc.SelectObject(solid)
            solidpen = wx.Pen(wx.Colour(75,75,75),wx.SOLID)
            dc.SetPen(solidpen)
            dc.DrawRectangle(0, 0, 200, 64)
            dc.SetTextForeground(wx.Colour(255, 255, 255))
            dc.DrawBitmap(wx.BitmapFromImage(bullet, 32), 10, 28)
            dc.DrawText(todo, 30,  24)
            dc.SelectObject(wx.NullBitmap)

            checked = wx.EmptyBitmap(200,64,-1)
            dc = wx.MemoryDC()
            dc.SelectObject(checked)
            checkedpen = wx.Pen(wx.Colour(50,50,50),wx.SOLID)
            dc.SetPen(checkedpen)
            dc.DrawRectangle(0, 0, 200, 50)
            dc.SetTextForeground(wx.Colour(200, 255, 0))
            dc.DrawBitmap(wx.BitmapFromImage(checkmark, 32), 6, 24)
            dc.DrawText(todo, 30,  24)
            dc.SelectObject(wx.NullBitmap)

            hover = wx.EmptyBitmap(200,64,-1)
            dc = wx.MemoryDC()
            dc.SelectObject(hover)
            hoverpen = wx.Pen(wx.Colour(100,100,100),wx.SOLID)
            dc.SetPen(hoverpen)
            dc.DrawRectangle(0, 0, 200, 64)
            dc.SetTextForeground(wx.Colour(255, 255, 255))
            dc.DrawBitmap(wx.BitmapFromImage(bullet, 32), 10, 28)
            dc.DrawText(todo, 30,  24)
            dc.SelectObject(wx.NullBitmap)

            important = wx.EmptyBitmap(200,64,-1)
            dc = wx.MemoryDC()
            dc.SelectObject(important)
            importantpen = wx.Pen(wx.Colour(75,75,75),wx.SOLID)
            dc.SetPen(importantpen)
            dc.DrawRectangle(0, 0, 200, 50)
            dc.SetTextForeground(wx.Colour(255, 180, 0))
            dc.DrawBitmap(wx.BitmapFromImage(exclaim, 32), 6, 24)
            dc.DrawText(todo, 30,  24)
            dc.SelectObject(wx.NullBitmap)

            importanthover = wx.EmptyBitmap(200,64,-1)
            dc = wx.MemoryDC()
            dc.SelectObject(importanthover)
            importanthoverpen = wx.Pen(wx.Colour(100,100,100),wx.SOLID)
            dc.SetPen(importanthoverpen)
            dc.DrawRectangle(0, 0, 200, 50)
            dc.SetTextForeground(wx.Colour(255, 180, 0))
            dc.DrawBitmap(wx.BitmapFromImage(exclaim, 32), 6, 24)
            dc.DrawText(todo, 30,  24)
            dc.SelectObject(wx.NullBitmap)

            if self.check is None and self.priority is None:
                bmp = solid
            elif self.priority is None:
                bmp = checked
            else:
                bmp = important       

            b = wx.BitmapButton(self, i + 800, bmp, (0,  i * 64), (solid.GetWidth(), solid.GetHeight()), style = wx.NO_BORDER)
            b.SetBitmapDisabled(checked)

            if self.check is None and self.priority is None:
                b.SetBitmapHover(hover)
            elif self.priority is None:
                b.SetBitmapHover(checked)
            else:
                b.SetBitmapHover(importanthover)

        Note.closed

    def OnClick(self, event):
        button = event.GetEventObject()
        button.None
        print('cheese')

    def OnEnter(self, event):
        editnote = open('note.txt', 'r+')
        editnote.write(self.input.GetValue())
        editnote.close()
        self.Update()

bdepth = pt.TL * 64 + 32
app = wx.App(False)
frame = MainWindow(None, "Sample editor")
app.MainLoop()

1 个答案:

答案 0 :(得分:1)

自己调用Update() Refresh()等没有意义。他们不会自动神奇地创建你的按钮,你需要这样做。

对于初学者,我会将您的__DoButtons()重构为两种方法,一种用于创建按钮,另一种用于从文件中获取按钮数据并将其格式化为适当的数据结构-a list(然后根据需要进行处理,然后将其传递给新的`__DoButtons方法(实际创建按钮)。

onEnter()中,您需要调用__DoButtons()方法并传入相应的数据,如果您只需要添加新按钮,为什么不直接从{{{ 1}}小部件,省去了从文件中读取它的麻烦。