in einer meiner Anwendungen verwende ich, unter anderem, eine Toolbar.
Da ich es mit dem Zeichnen nicht so habe, erzeuge ich die notwendigen Bitmaps aus Zeichenketten.
Meine Vorgehensweise:
- Die grösse des Texts in Pixeln wird berechnet
- Eine leere Bitmap wird erzeugt, die in Höhe und Breite 6 Pixel mehr hat
- Ein Rechteck mit abgerundeten Ecken wird gezeichnet
- und der Text mittig dazu eingefügt
Unter Windows (XP und 7) ist es leider nicht brauchbar:
- Alles ausserhalb des Rechtecks wird nicht transparent, sondern schwarz gezeichnet (noch harmlos)
- Alle Schaltflächen sind so breit wie die breiteste Bitmap (Unter OS X sind die Schaltflächen so breit wie die dazu gehörige Bitmap)
Wenn Ja: Wie realisiere ich das mit wxPython ?
Wenn Nein: Wie könnte man etwas Ähnliches erreichen (Plattform unabhängig bevorzugt)
Hier etwas Code zum Nachstellen:
Code: Alles auswählen
#!/usr/bin/env python
# coding: utf-8
import wx
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,
parent=None,
title=u"Test"
)
self.CreateStatusBar()
self.view = wx.Panel(self)
self.create_toolbar((
("Quit", self.on_quit),
("Prefs", self.on_dummy),
("", None),
("Update", None),
("", None),
("Add", self.on_dummy),
("Del", self.on_dummy),
("Clear finished", self.on_dummy),
))
self.Show()
def create_toolbar(self, data):
self.tb_data = dict()
self.toolbar = self.CreateToolBar()
for text, handler in data:
if text:
width, height = wx.ScreenDC().GetTextExtent(text)
bitmap = wx.EmptyBitmap(width+6, height+6)
dc = wx.MemoryDC(bitmap)
dc.DrawRoundedRectangle(0, 0, width+6, height+6, 5)
dc.DrawText(text, 3, 3)
id = wx.NewId()
item = self.toolbar.AddLabelTool(id=id, label=text, bitmap=bitmap)
self.Bind(wx.EVT_MENU, handler, item)
self.tb_data[text] = id
self.tool_state(text, bool(handler))
else:
self.toolbar.AddSeparator()
self.toolbar.Realize()
def tool_state(self, name, state):
self.toolbar.EnableTool(self.tb_data[name], state)
def on_quit(self, event):
self.Close()
def on_dummy(self, event):
pass
def main():
app = wx.App(redirect=False)
MainFrame()
app.MainLoop()
if __name__ == "__main__":
main()